neuron-client 0.2.6 → 0.3.0

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 (116) hide show
  1. data/README.md +11 -8
  2. data/lib/neuron-client/api.rb +5 -0
  3. data/lib/neuron-client/model/ad.rb +142 -0
  4. data/lib/neuron-client/model/ad_calculations.rb +325 -0
  5. data/lib/neuron-client/model/ad_zone.rb +45 -0
  6. data/lib/neuron-client/model/base.rb +233 -18
  7. data/lib/neuron-client/model/blocked_referer.rb +20 -0
  8. data/lib/neuron-client/model/blocked_user_agent.rb +21 -0
  9. data/lib/neuron-client/model/geo_target.rb +36 -0
  10. data/lib/neuron-client/model/pixel.rb +22 -0
  11. data/lib/neuron-client/model/report.rb +35 -0
  12. data/lib/neuron-client/model/s3_file.rb +30 -0
  13. data/lib/neuron-client/model/zone.rb +64 -0
  14. data/lib/neuron-client/model/zone_calculations.rb +37 -0
  15. data/lib/neuron-client/schema/ad.rb +406 -0
  16. data/lib/neuron-client/schema/ad_zone.rb +49 -0
  17. data/lib/neuron-client/schema/blocked_referer.rb +52 -0
  18. data/lib/neuron-client/schema/blocked_user_agent.rb +64 -0
  19. data/lib/neuron-client/schema/common.rb +220 -0
  20. data/lib/neuron-client/schema/event.rb +17 -0
  21. data/lib/neuron-client/schema/geo_target.rb +33 -0
  22. data/lib/neuron-client/schema/pixel.rb +39 -0
  23. data/lib/neuron-client/schema/report.rb +59 -0
  24. data/lib/neuron-client/schema/s3_file.rb +87 -0
  25. data/lib/neuron-client/schema/zone.rb +214 -0
  26. data/lib/neuron-client/version.rb +1 -1
  27. data/lib/neuron-client.rb +24 -59
  28. data/neuron-client.gemspec +3 -0
  29. data/spec/lib/admin_connection_spec.rb +234 -0
  30. data/spec/lib/api_spec.rb +41 -63
  31. data/spec/lib/model/ad_calculations_spec.rb +1146 -0
  32. data/spec/lib/model/ad_spec.rb +253 -0
  33. data/spec/lib/model/ad_zone_spec.rb +15 -0
  34. data/spec/lib/model/base_spec.rb +5 -83
  35. data/spec/lib/model/blocked_referer_spec.rb +36 -0
  36. data/spec/lib/model/blocked_user_agent_spec.rb +36 -0
  37. data/spec/lib/model/geo_target_spec.rb +28 -0
  38. data/spec/lib/model/pixel_spec.rb +36 -0
  39. data/spec/lib/model/report_spec.rb +17 -0
  40. data/spec/lib/{s3_file_spec.rb → model/s3_file_spec.rb} +6 -5
  41. data/spec/lib/model/zone_calculations_spec.rb +49 -0
  42. data/spec/lib/model/zone_spec.rb +155 -0
  43. data/spec/lib/schema/ad_spec.rb +515 -0
  44. data/spec/lib/schema/ad_zone_spec.rb +149 -0
  45. data/spec/lib/schema/blocked_referer_spec.rb +136 -0
  46. data/spec/lib/schema/blocked_user_agent_spec.rb +147 -0
  47. data/spec/lib/schema/geo_target_spec.rb +92 -0
  48. data/spec/lib/schema/pixel_spec.rb +125 -0
  49. data/spec/lib/schema/report_spec.rb +129 -0
  50. data/spec/lib/schema/s3_file_spec.rb +164 -0
  51. data/spec/lib/schema/zone_spec.rb +243 -0
  52. data/spec/spec_helper.rb +2 -1
  53. metadata +141 -121
  54. data/lib/neuron-client/model/admin/ad.rb +0 -22
  55. data/lib/neuron-client/model/admin/ad_zone.rb +0 -15
  56. data/lib/neuron-client/model/admin/base.rb +0 -91
  57. data/lib/neuron-client/model/admin/blocked_referer.rb +0 -12
  58. data/lib/neuron-client/model/admin/blocked_user_agent.rb +0 -12
  59. data/lib/neuron-client/model/admin/geo_target.rb +0 -16
  60. data/lib/neuron-client/model/admin/pixel.rb +0 -12
  61. data/lib/neuron-client/model/admin/report.rb +0 -15
  62. data/lib/neuron-client/model/admin/s3_file.rb +0 -12
  63. data/lib/neuron-client/model/admin/zone.rb +0 -15
  64. data/lib/neuron-client/model/common/ad.rb +0 -42
  65. data/lib/neuron-client/model/common/ad_calculations.rb +0 -329
  66. data/lib/neuron-client/model/common/ad_zone.rb +0 -17
  67. data/lib/neuron-client/model/common/base.rb +0 -67
  68. data/lib/neuron-client/model/common/blocked_referer.rb +0 -16
  69. data/lib/neuron-client/model/common/blocked_user_agent.rb +0 -16
  70. data/lib/neuron-client/model/common/geo_target.rb +0 -16
  71. data/lib/neuron-client/model/common/pixel.rb +0 -18
  72. data/lib/neuron-client/model/common/report.rb +0 -21
  73. data/lib/neuron-client/model/common/s3_file.rb +0 -16
  74. data/lib/neuron-client/model/common/zone.rb +0 -22
  75. data/lib/neuron-client/model/common/zone_calculations.rb +0 -41
  76. data/lib/neuron-client/model/membase/ad.rb +0 -49
  77. data/lib/neuron-client/model/membase/ad_zone.rb +0 -11
  78. data/lib/neuron-client/model/membase/blocked_referer.rb +0 -20
  79. data/lib/neuron-client/model/membase/blocked_user_agent.rb +0 -20
  80. data/lib/neuron-client/model/membase/geo_target.rb +0 -11
  81. data/lib/neuron-client/model/membase/pixel.rb +0 -22
  82. data/lib/neuron-client/model/membase/report.rb +0 -11
  83. data/lib/neuron-client/model/membase/s3_file.rb +0 -11
  84. data/lib/neuron-client/model/membase/zone.rb +0 -30
  85. data/lib/neuron-client/model/models.rb +0 -15
  86. data/spec/lib/model/admin/ad_spec.rb +0 -34
  87. data/spec/lib/model/admin/ad_zone_spec.rb +0 -19
  88. data/spec/lib/model/admin/base_spec.rb +0 -11
  89. data/spec/lib/model/admin/blocked_referer_spec.rb +0 -11
  90. data/spec/lib/model/admin/blocked_user_agent_spec.rb +0 -11
  91. data/spec/lib/model/admin/geo_target_spec.rb +0 -30
  92. data/spec/lib/model/admin/report_spec.rb +0 -21
  93. data/spec/lib/model/admin/s3_spec.rb +0 -11
  94. data/spec/lib/model/admin/zone_spec.rb +0 -21
  95. data/spec/lib/model/common/ad_calculations_spec.rb +0 -1151
  96. data/spec/lib/model/common/ad_spec.rb +0 -11
  97. data/spec/lib/model/common/ad_zone_spec.rb +0 -11
  98. data/spec/lib/model/common/base_spec.rb +0 -11
  99. data/spec/lib/model/common/blocked_referer_spec.rb +0 -11
  100. data/spec/lib/model/common/blocked_user_agent_spec.rb +0 -11
  101. data/spec/lib/model/common/geo_target_spec.rb +0 -11
  102. data/spec/lib/model/common/report_spec.rb +0 -11
  103. data/spec/lib/model/common/s3_spec.rb +0 -11
  104. data/spec/lib/model/common/zone_calculations_spec.rb +0 -54
  105. data/spec/lib/model/common/zone_spec.rb +0 -11
  106. data/spec/lib/model/membase/ad_spec.rb +0 -54
  107. data/spec/lib/model/membase/ad_zone_spec.rb +0 -11
  108. data/spec/lib/model/membase/base_spec.rb +0 -11
  109. data/spec/lib/model/membase/blocked_referer_spec.rb +0 -34
  110. data/spec/lib/model/membase/blocked_user_agent_spec.rb +0 -34
  111. data/spec/lib/model/membase/geo_target_spec.rb +0 -11
  112. data/spec/lib/model/membase/pixel_spec.rb +0 -34
  113. data/spec/lib/model/membase/report_spec.rb +0 -11
  114. data/spec/lib/model/membase/s3_spec.rb +0 -11
  115. data/spec/lib/model/membase/zone_spec.rb +0 -32
  116. data/spec/lib/old_spec.rb +0 -437
@@ -1,329 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- module AdCalculations
6
- # This module expects the following methods to be defined:
7
- # start_datetime (Time, String, or nil)
8
- # end_datetime (Time, String, or nil)
9
- # time_zone (String)
10
- # day_partitions (String, or nil, length = 7*24, matches /^[TF]+$/)
11
- # daily_cap (FixNum, or nil)
12
- # overall_cap (FixNum, or nil)
13
- # ideal_impressions_per_hour (Number, or nil)
14
- # total_impressed (Integer, >= 0)
15
- # today_impressed (Integer, >= 0)
16
-
17
- def active?
18
- calculate_active?(Time.now, total_impressed, today_impressed)
19
- end
20
-
21
- def pressure
22
- calculate_pressure(Time.now, total_impressed, today_impressed)
23
- end
24
-
25
- def calculate_active?(time, total, today)
26
- time = time.in_time_zone(time_zone)
27
- return false unless within_date_range?(time)
28
- return false if partitioned? && !partitioned_hour?(time)
29
- !cap_met?(total, today)
30
- end
31
-
32
- # Set the optional "active" parameter to true or false if you already know
33
- def calculate_pressure(time, total, today, active=nil)
34
- return nil if active == false
35
- return nil unless active || calculate_active?(time,total,today)
36
- time = time.in_time_zone(time_zone)
37
- if daily_capped?
38
- if daily_cap_precludes_overall_cap?(time,total,today)
39
- calculate_overall_pressure(time, total)
40
- else
41
- calculate_today_pressure(time, today)
42
- end
43
- elsif overall_pressure_exists?
44
- calculate_overall_pressure(time, total)
45
- else
46
- (ideal_impressions_per_hour || 1.0).to_f
47
- end
48
- end
49
-
50
- private
51
-
52
- def in_ad_time_zone(time)
53
- if time.present?
54
- (time.is_a?(String) ? Time.parse(time) : time).in_time_zone(time_zone)
55
- end
56
- rescue
57
- nil
58
- end
59
-
60
- def start_in_time_zone
61
- in_ad_time_zone(start_datetime)
62
- end
63
-
64
- def end_in_time_zone
65
- in_ad_time_zone(end_datetime)
66
- end
67
-
68
- def daily_capped?
69
- !daily_cap.nil? && daily_cap >= 0
70
- end
71
-
72
- def overall_capped?
73
- !overall_cap.nil? && overall_cap >= 0
74
- end
75
-
76
- def overall_pressure_exists?
77
- overall_capped? && end_datetime.present?
78
- end
79
-
80
- def partitioned?
81
- !day_partitions.nil? && day_partitions.length == 24*7
82
- end
83
-
84
- def within_date_range?(time)
85
- return false if start_datetime.present? && time < start_in_time_zone
86
- return false if end_datetime.present? && time >= end_in_time_zone
87
- true
88
- end
89
-
90
- # Assume time is in the time zone of the ad.
91
- # Doesn't worry about whether or not the time is in the ad's date range.
92
- # Assumes ad is partitioned.
93
- def partitioned_hour?(time)
94
- day_partitions.at((time.wday * 24) + time.hour) == 'T'
95
- end
96
-
97
- # Assume time is in the time zone of the ad.
98
- # Doesn't worry about whether or not the time is in the ad's date range.
99
- # Assumes ad is partitioned.
100
- # Returns true if there is any active partition the day of the given time.
101
- def partitioned_day?(time)
102
- day_partitions[(time.wday) * 24, 24].include?('T')
103
- end
104
-
105
- # Assumes time is in the time zone of the ad.
106
- # Doesn't worry about date range or day partitions.
107
- def cap_met?(total_impressed, today_impressed)
108
- return true if daily_capped? && (daily_cap <= today_impressed)
109
- return true if overall_capped? && (overall_cap <= total_impressed)
110
- false
111
- end
112
-
113
- # Assumes time is in time_zone of the ad.
114
- # Returns true if there's no way we can hit the overall cap
115
- # without busting the daily cap.
116
- def daily_cap_precludes_overall_cap?(time,total_impressed,today_impressed)
117
- return false unless daily_capped? && overall_capped?
118
- return false unless self.end_datetime.present?
119
- a = remaining_impressions_via_daily_cap(time, today_impressed)
120
- b = remaining_impressions_via_overall_cap(total_impressed)
121
- a < b
122
- end
123
-
124
- def remaining_impressions_via_overall_cap(total_impressed)
125
- [overall_cap - total_impressed, 0].max
126
- end
127
-
128
- def remaining_impressions_today(today_impressed)
129
- [daily_cap - today_impressed, 0].max
130
- end
131
-
132
- def remaining_impressions_via_daily_cap(time, today_impressed)
133
- days = remaining_days(time) - 1 # exclude today
134
- daily_cap * days + remaining_impressions_today(today_impressed)
135
- end
136
-
137
- # Assumes time is in time_zone of the ad.
138
- # Assume daily_cap is present.
139
- def calculate_today_pressure(time, today_impressed)
140
- hours = remaining_hours_today(time)
141
- if hours <= 0
142
- 0.0
143
- else
144
- impressions = remaining_impressions_today(today_impressed)
145
- 2 * impressions / hours.to_f
146
- end
147
- end
148
-
149
- # Assumes time is in time_zone of the ad.
150
- # Assume overall_cap is present.
151
- # Assume end_datetime is present.
152
- def calculate_overall_pressure(time, total_impressed)
153
- hours = remaining_hours(time)
154
- if hours <= 0
155
- 0.0
156
- else
157
- impressions = remaining_impressions_via_overall_cap(total_impressed)
158
- impressions / hours.to_f
159
- end
160
- end
161
-
162
- # remaining_days : the total integer number of days that an ad will run
163
- # (even for part of the day) between now and the
164
- # end_datetime.
165
- # Assume all dates/times are in the time_zone of the ad.
166
- # Assume end_datetime is present.
167
- def remaining_days(time)
168
- ending = end_in_time_zone
169
- beginning = [time, start_in_time_zone].compact.max
170
- return 0 unless beginning < ending
171
- if partitioned?
172
- end_of_beginning_week = beginning_of_week(beginning) + 7.days
173
- beginning_of_end_week = beginning_of_week(ending)
174
-
175
- if end_of_beginning_week < beginning_of_end_week
176
- head_days = partitioned_days(beginning, end_of_beginning_week)
177
- tail_days = partitioned_days(beginning_of_end_week, ending)
178
- whole_weeks = (beginning_of_end_week-end_of_beginning_week) / 7.days
179
- head_days + (whole_weeks * days_per_week) + tail_days
180
- else
181
- partitioned_days(beginning, ending)
182
- end
183
- else
184
- (ending.beginning_of_day.to_datetime -
185
- beginning.beginning_of_day.to_datetime) + 1
186
- end
187
- end
188
-
189
- # remaining_hours : the total number of hours that an ad will run from now
190
- # to the end_datetime, taking day parting into account.
191
- # Assume all dates/times are in the time_zone of the ad.
192
- def remaining_hours(time)
193
- ending = end_in_time_zone
194
- beginning = [time, start_in_time_zone].compact.max
195
- return 0 unless beginning < ending
196
- if partitioned?
197
-
198
- end_of_beginning_week = beginning_of_week(beginning) + 7.days
199
- beginning_of_end_week = beginning_of_week(ending)
200
-
201
- if end_of_beginning_week < beginning_of_end_week
202
- head_hours = partitioned_hours(beginning, end_of_beginning_week)
203
- tail_hours = partitioned_hours(beginning_of_end_week, ending)
204
- whole_weeks = (beginning_of_end_week-end_of_beginning_week) / 7.days
205
- head_hours + (whole_weeks * hours_per_week) + tail_hours
206
- else
207
- partitioned_hours(beginning, ending)
208
- end
209
- else
210
- actual_hours(beginning, ending)
211
- end
212
- end
213
-
214
- # remaining_hours_today : the total number of hours that an ad will run
215
- # between now and the end of the day, taking day
216
- # parting into account.
217
- # Assume all dates/times are in the time_zone of the ad.
218
- def remaining_hours_today(time)
219
- beginning = [time, start_in_time_zone].compact.max
220
- ending = [time.beginning_of_day + 1.day, end_in_time_zone].compact.min
221
- return 0 unless beginning < ending
222
- if partitioned?
223
- partitioned_hours(beginning, ending)
224
- else
225
- actual_hours(beginning, ending)
226
- end
227
- end
228
-
229
- # Assume time is in the time_zone of the ad.
230
- # Assume a week begins on Sunday.
231
- def beginning_of_week(time)
232
- recent_monday = time.monday
233
- sunday_before_recent_monday = recent_monday - 1.day
234
- if (time - sunday_before_recent_monday) < 7.days
235
- sunday_before_recent_monday
236
- else
237
- sunday_before_recent_monday + 7.days
238
- end
239
- end
240
-
241
- def beginning_of_hour(time)
242
- time.change(:min => 0, :sec => 0, :usec => 0)
243
- end
244
-
245
- # Assume beginning and ending are in the ad's time_zone.
246
- # Assume beginning and ending are within the ad's date range.
247
- # Assume ad is partitioned.
248
- def partitioned_hours(beginning, ending)
249
- return 0 unless beginning < ending
250
- total = 0.0
251
- this_hour = beginning_of_hour(beginning)
252
- last_hour = beginning_of_hour(ending)
253
- if this_hour.to_i == last_hour.to_i
254
- if partitioned_hour?(this_hour)
255
- total = actual_hours(beginning, ending)
256
- end
257
- else
258
- next_hour = this_hour + 1.hour
259
- if partitioned_hour?(this_hour)
260
- total += actual_hours(beginning, next_hour)
261
- end
262
- each_hour(next_hour, last_hour) do |hour|
263
- total += 1 if partitioned_hour?(hour)
264
- end
265
- if partitioned_hour?(last_hour)
266
- total += actual_hours(last_hour, ending)
267
- end
268
- end
269
- total
270
- end
271
-
272
- # Assume beginning and ending are in the ad's time_zone.
273
- # Assume beginning and ending are within the ad's date range.
274
- # Assume ad is partitioned.
275
- # Assume beginning and ending are within a week of each other.
276
- # Computes integer number of days where any part of the day is active.
277
- def partitioned_days(beginning, ending)
278
- return 0 unless beginning < ending
279
-
280
- end_of_beginning_day = beginning.beginning_of_day + 1.day
281
- beginning_of_end_day = ending.beginning_of_day
282
-
283
- if end_of_beginning_day < beginning_of_end_day
284
- days = 0
285
- days += 1 if partitioned_hours(beginning, end_of_beginning_day) > 0
286
- days += 1 if partitioned_hours(beginning_of_end_day, ending) > 0
287
- each_day(end_of_beginning_day, beginning_of_end_day) do |day|
288
- days += 1 if partitioned_day?(day)
289
- end
290
- days
291
- else
292
- (partitioned_hours(beginning,ending) > 0) ? 1 : 0
293
- end
294
- end
295
-
296
- def each_day(beginning, ending)
297
- time = beginning.clone
298
- while (time < ending)
299
- yield time
300
- time += 1.day
301
- end
302
- end
303
-
304
- def each_hour(beginning, ending)
305
- time = beginning.clone
306
- while(time < ending)
307
- yield time
308
- time += 1.hour
309
- end
310
- end
311
-
312
- def actual_hours(beginning, ending)
313
- (ending.to_f - beginning.to_f) / 3600
314
- end
315
-
316
- # Assumes ad is partitioned.
317
- def days_per_week
318
- (0..6).map{|d| day_partitions[d*24,24].include?('T') ? 1 : 0 }.sum
319
- end
320
-
321
- # Assumes ad is partitioned.
322
- def hours_per_week
323
- day_partitions.count("T")
324
- end
325
- end
326
- end
327
- end
328
- end
329
- end
@@ -1,17 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- class AdZone
6
- include Base
7
-
8
- resource_name("ad_zone")
9
- resources_name("ad_zones")
10
-
11
- attr_accessor :ad_id, :zone_id, :priority, :weight,
12
- :created_at, :updated_at
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,67 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- module Base
6
- def initialize(attrs=nil)
7
- (attrs || {}).each do |k,v|
8
- next if k.to_s == 'id' && self.class.remote_id != 'id'
9
- k = 'id' if k.to_s == self.class.remote_id
10
- self.send("#{k}=", v) if self.respond_to?("#{k}=")
11
- end
12
- end
13
-
14
- def self.included(base)
15
- base.send(:attr_accessor, :id)
16
- base.extend(ClassMethods)
17
- end
18
-
19
- module ClassMethods
20
- def api
21
- class_name_to_load = superclass.name.split('::').last
22
- Neuron::Client::Model.const_get(class_name_to_load).api
23
- end
24
-
25
- def connection
26
- api.connection
27
- end
28
-
29
- def attr_accessor(*vars)
30
- @attributes ||= []
31
- @attributes += vars
32
- super(*vars)
33
- end
34
-
35
- def attributes
36
- @attributes
37
- end
38
-
39
- def resource_name(res=nil)
40
- if res
41
- @resource_name = res.to_s
42
- end
43
- @resource_name
44
- end
45
-
46
- def resources_name(res=nil)
47
- if res
48
- @resources_name = res.to_s.downcase
49
- end
50
- if @resources_name.nil? && !@resource_name.nil?
51
- @resources_name = "#{@resource_name}s"
52
- end
53
- @resources_name
54
- end
55
-
56
- def remote_id(remote_id=nil)
57
- if remote_id
58
- @remote_id = remote_id.to_s
59
- end
60
- @remote_id || 'id'
61
- end
62
- end
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,16 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- class BlockedReferer
6
- include Base
7
-
8
- resource_name("blocked_referer")
9
- resources_name("blocked_referers")
10
-
11
- attr_accessor :referer, :reversed_referer, :created_at, :updated_at
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,16 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- class BlockedUserAgent
6
- include Base
7
-
8
- resource_name("blocked_user_agent")
9
- resources_name("blocked_user_agents")
10
-
11
- attr_accessor :user_agent, :description, :created_at, :updated_at
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,16 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- class GeoTarget
6
- include Base
7
-
8
- resource_name("geo_target")
9
- resources_name("geo_targets")
10
-
11
- attr_accessor :geo_type, :full_name, :name, :abbreviation, :updated_at
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,18 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- class Pixel
6
- include Base
7
-
8
- resource_name("pixel")
9
- resources_name("pixels")
10
-
11
- # time stamps
12
- attr_accessor :created_at, :updated_at
13
-
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,21 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- class Report
6
- include Base
7
-
8
- resource_name("report")
9
- resources_name("reports")
10
-
11
- attr_accessor :errors
12
- attr_accessor :template, :parameters, :state
13
-
14
- def status
15
- @state
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,16 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- class S3File
6
- include Base
7
-
8
- resource_name("s3_file")
9
- resources_name("s3_files")
10
-
11
- attr_accessor :bucket, :filename, :purpose, :filesize, :created_at, :updated_at
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,22 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- class Zone
6
- include Base
7
- include ZoneCalculations
8
-
9
- resource_name("zone")
10
- resources_name("zones")
11
-
12
- attr_accessor :slug, :response_type, :template_slug, :parameters,
13
- :created_at, :updated_at, :ad_links
14
-
15
- def find_ad(ad_id)
16
- Neuron::Client::Model::Ad.find(ad_id)
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,41 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
- module ZoneCalculations
6
- # This module expects the following methods to be defined:
7
- #
8
- # ad_links (Hash, keys are ad IDs, values are a sub-hash: {'priority' => p, 'weight' => w})
9
- # find_ad(ad_id) (nil, or an object that responds to :active? and :pressure)
10
-
11
- def ads_by_priority
12
- calculate_ads_by_priority
13
- end
14
-
15
- def calculate_ads_by_priority
16
- entries = {}
17
- ad_links.each do |ad_id, link|
18
- next unless ad = find_ad(ad_id)
19
- next unless ad.active?
20
- weight = link['weight'].to_f
21
- priority = link['priority'].to_f
22
- entries[priority] ||= []
23
- entries[priority] << [ad_id, weighted_pressure(weight, ad.pressure)]
24
- end
25
- entries.sort_by do |priority, entry|
26
- priority
27
- end.map do |priority, entry|
28
- entry.sort_by(&:first)
29
- end
30
- end
31
-
32
- private
33
-
34
- def weighted_pressure(weight, pressure)
35
- [( [weight, 0.0].max * [pressure, 1.0].max ), 1.0].max.to_f
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,49 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Membase
5
- class Ad < Common::Ad
6
-
7
- ACTIVE_TTL = 60 #seconds
8
- PRESSURE_TTL = 60 #seconds
9
-
10
- def total_impressed
11
- key = "count_delivery_ad_#{self.id}"
12
- self.class.connection.get(key,1).to_f
13
- end
14
-
15
- def today_impressed
16
- now_adjusted_for_ad_time_zone = Time.now.in_time_zone(self.time_zone)
17
- formatted_date = now_adjusted_for_ad_time_zone.strftime('%Y%m%d') # format to YYYYMMDD
18
- key = "count_delivery_#{formatted_date}_ad_#{self.id}"
19
- self.class.connection.get(key,1).to_f
20
- end
21
-
22
- def active?
23
- self.class.connection.fetch("Ad:#{id}:active", ACTIVE_TTL) do
24
- calculate_active?(Time.now, total_impressed, today_impressed)
25
- end
26
- end
27
-
28
- def pressure
29
- self.class.connection.fetch("Ad:#{id}:pressure", PRESSURE_TTL) do
30
- calculate_pressure(Time.now, total_impressed, today_impressed)
31
- end
32
- end
33
-
34
- class << self
35
- def find(id)
36
- self.connection.local_cache.fetch("Neuron::Client::Model::Ad:#{id}") do
37
- ad = nil
38
- membase_key = "Ad:#{id}"
39
- cached_json = self.connection.get(membase_key)
40
- ad = self.new(Yajl.load(cached_json)[superclass.resource_name]) if cached_json.present?
41
- ad
42
- end
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,11 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Membase
5
- class AdZone < Common::AdZone
6
-
7
- end
8
- end
9
- end
10
- end
11
- end
@@ -1,20 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Membase
5
- class BlockedReferer < Common::BlockedReferer
6
- class << self
7
- def all
8
- self.connection.local_cache.fetch("Neuron::Client::Model::BlockedReferer:all") do
9
- blocked_referers = []
10
- cached_json = self.connection.get('blocked_referers')
11
- blocked_referers = Yajl.load(cached_json).collect{|item| self.new(item[superclass.resource_name])} if cached_json.present?
12
- blocked_referers
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,20 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Membase
5
- class BlockedUserAgent < Common::BlockedUserAgent
6
- class << self
7
- def all
8
- self.connection.local_cache.fetch("Neuron::Client::Model::BlockedUserAgent:all") do
9
- blocked_user_agents = []
10
- cached_json = self.connection.get('blocked_user_agents')
11
- blocked_user_agents = Yajl.load(cached_json).collect{|item| self.new(item[superclass.resource_name])} if cached_json.present?
12
- blocked_user_agents
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end