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.
- data/README.md +11 -8
- data/lib/neuron-client/api.rb +5 -0
- data/lib/neuron-client/model/ad.rb +142 -0
- data/lib/neuron-client/model/ad_calculations.rb +325 -0
- data/lib/neuron-client/model/ad_zone.rb +45 -0
- data/lib/neuron-client/model/base.rb +233 -18
- data/lib/neuron-client/model/blocked_referer.rb +20 -0
- data/lib/neuron-client/model/blocked_user_agent.rb +21 -0
- data/lib/neuron-client/model/geo_target.rb +36 -0
- data/lib/neuron-client/model/pixel.rb +22 -0
- data/lib/neuron-client/model/report.rb +35 -0
- data/lib/neuron-client/model/s3_file.rb +30 -0
- data/lib/neuron-client/model/zone.rb +64 -0
- data/lib/neuron-client/model/zone_calculations.rb +37 -0
- data/lib/neuron-client/schema/ad.rb +406 -0
- data/lib/neuron-client/schema/ad_zone.rb +49 -0
- data/lib/neuron-client/schema/blocked_referer.rb +52 -0
- data/lib/neuron-client/schema/blocked_user_agent.rb +64 -0
- data/lib/neuron-client/schema/common.rb +220 -0
- data/lib/neuron-client/schema/event.rb +17 -0
- data/lib/neuron-client/schema/geo_target.rb +33 -0
- data/lib/neuron-client/schema/pixel.rb +39 -0
- data/lib/neuron-client/schema/report.rb +59 -0
- data/lib/neuron-client/schema/s3_file.rb +87 -0
- data/lib/neuron-client/schema/zone.rb +214 -0
- data/lib/neuron-client/version.rb +1 -1
- data/lib/neuron-client.rb +24 -59
- data/neuron-client.gemspec +3 -0
- data/spec/lib/admin_connection_spec.rb +234 -0
- data/spec/lib/api_spec.rb +41 -63
- data/spec/lib/model/ad_calculations_spec.rb +1146 -0
- data/spec/lib/model/ad_spec.rb +253 -0
- data/spec/lib/model/ad_zone_spec.rb +15 -0
- data/spec/lib/model/base_spec.rb +5 -83
- data/spec/lib/model/blocked_referer_spec.rb +36 -0
- data/spec/lib/model/blocked_user_agent_spec.rb +36 -0
- data/spec/lib/model/geo_target_spec.rb +28 -0
- data/spec/lib/model/pixel_spec.rb +36 -0
- data/spec/lib/model/report_spec.rb +17 -0
- data/spec/lib/{s3_file_spec.rb → model/s3_file_spec.rb} +6 -5
- data/spec/lib/model/zone_calculations_spec.rb +49 -0
- data/spec/lib/model/zone_spec.rb +155 -0
- data/spec/lib/schema/ad_spec.rb +515 -0
- data/spec/lib/schema/ad_zone_spec.rb +149 -0
- data/spec/lib/schema/blocked_referer_spec.rb +136 -0
- data/spec/lib/schema/blocked_user_agent_spec.rb +147 -0
- data/spec/lib/schema/geo_target_spec.rb +92 -0
- data/spec/lib/schema/pixel_spec.rb +125 -0
- data/spec/lib/schema/report_spec.rb +129 -0
- data/spec/lib/schema/s3_file_spec.rb +164 -0
- data/spec/lib/schema/zone_spec.rb +243 -0
- data/spec/spec_helper.rb +2 -1
- metadata +141 -121
- data/lib/neuron-client/model/admin/ad.rb +0 -22
- data/lib/neuron-client/model/admin/ad_zone.rb +0 -15
- data/lib/neuron-client/model/admin/base.rb +0 -91
- data/lib/neuron-client/model/admin/blocked_referer.rb +0 -12
- data/lib/neuron-client/model/admin/blocked_user_agent.rb +0 -12
- data/lib/neuron-client/model/admin/geo_target.rb +0 -16
- data/lib/neuron-client/model/admin/pixel.rb +0 -12
- data/lib/neuron-client/model/admin/report.rb +0 -15
- data/lib/neuron-client/model/admin/s3_file.rb +0 -12
- data/lib/neuron-client/model/admin/zone.rb +0 -15
- data/lib/neuron-client/model/common/ad.rb +0 -42
- data/lib/neuron-client/model/common/ad_calculations.rb +0 -329
- data/lib/neuron-client/model/common/ad_zone.rb +0 -17
- data/lib/neuron-client/model/common/base.rb +0 -67
- data/lib/neuron-client/model/common/blocked_referer.rb +0 -16
- data/lib/neuron-client/model/common/blocked_user_agent.rb +0 -16
- data/lib/neuron-client/model/common/geo_target.rb +0 -16
- data/lib/neuron-client/model/common/pixel.rb +0 -18
- data/lib/neuron-client/model/common/report.rb +0 -21
- data/lib/neuron-client/model/common/s3_file.rb +0 -16
- data/lib/neuron-client/model/common/zone.rb +0 -22
- data/lib/neuron-client/model/common/zone_calculations.rb +0 -41
- data/lib/neuron-client/model/membase/ad.rb +0 -49
- data/lib/neuron-client/model/membase/ad_zone.rb +0 -11
- data/lib/neuron-client/model/membase/blocked_referer.rb +0 -20
- data/lib/neuron-client/model/membase/blocked_user_agent.rb +0 -20
- data/lib/neuron-client/model/membase/geo_target.rb +0 -11
- data/lib/neuron-client/model/membase/pixel.rb +0 -22
- data/lib/neuron-client/model/membase/report.rb +0 -11
- data/lib/neuron-client/model/membase/s3_file.rb +0 -11
- data/lib/neuron-client/model/membase/zone.rb +0 -30
- data/lib/neuron-client/model/models.rb +0 -15
- data/spec/lib/model/admin/ad_spec.rb +0 -34
- data/spec/lib/model/admin/ad_zone_spec.rb +0 -19
- data/spec/lib/model/admin/base_spec.rb +0 -11
- data/spec/lib/model/admin/blocked_referer_spec.rb +0 -11
- data/spec/lib/model/admin/blocked_user_agent_spec.rb +0 -11
- data/spec/lib/model/admin/geo_target_spec.rb +0 -30
- data/spec/lib/model/admin/report_spec.rb +0 -21
- data/spec/lib/model/admin/s3_spec.rb +0 -11
- data/spec/lib/model/admin/zone_spec.rb +0 -21
- data/spec/lib/model/common/ad_calculations_spec.rb +0 -1151
- data/spec/lib/model/common/ad_spec.rb +0 -11
- data/spec/lib/model/common/ad_zone_spec.rb +0 -11
- data/spec/lib/model/common/base_spec.rb +0 -11
- data/spec/lib/model/common/blocked_referer_spec.rb +0 -11
- data/spec/lib/model/common/blocked_user_agent_spec.rb +0 -11
- data/spec/lib/model/common/geo_target_spec.rb +0 -11
- data/spec/lib/model/common/report_spec.rb +0 -11
- data/spec/lib/model/common/s3_spec.rb +0 -11
- data/spec/lib/model/common/zone_calculations_spec.rb +0 -54
- data/spec/lib/model/common/zone_spec.rb +0 -11
- data/spec/lib/model/membase/ad_spec.rb +0 -54
- data/spec/lib/model/membase/ad_zone_spec.rb +0 -11
- data/spec/lib/model/membase/base_spec.rb +0 -11
- data/spec/lib/model/membase/blocked_referer_spec.rb +0 -34
- data/spec/lib/model/membase/blocked_user_agent_spec.rb +0 -34
- data/spec/lib/model/membase/geo_target_spec.rb +0 -11
- data/spec/lib/model/membase/pixel_spec.rb +0 -34
- data/spec/lib/model/membase/report_spec.rb +0 -11
- data/spec/lib/model/membase/s3_spec.rb +0 -11
- data/spec/lib/model/membase/zone_spec.rb +0 -32
- data/spec/lib/old_spec.rb +0 -437
|
@@ -1,37 +1,252 @@
|
|
|
1
1
|
module Neuron
|
|
2
2
|
module Client
|
|
3
|
-
module
|
|
4
|
-
class Base
|
|
5
|
-
instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id|^class$)/ }
|
|
3
|
+
module Base
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
module ClassAndInstanceMethods
|
|
6
|
+
|
|
7
|
+
def find(id)
|
|
8
|
+
if connected_to_membase?
|
|
9
|
+
key = cache_key(id)
|
|
10
|
+
connection.local_cache.fetch(key) do
|
|
11
|
+
cached_json = connection.get(key)
|
|
12
|
+
if cached_json.present?
|
|
13
|
+
data = Yajl.load(cached_json)
|
|
14
|
+
validate_against_schema!(:show, data)
|
|
15
|
+
from_hash(data)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
elsif connected_to_admin?
|
|
19
|
+
data = connection.get("#{resources_name}/#{id}")
|
|
20
|
+
validate_against_schema!(:show, data)
|
|
21
|
+
from_hash(data)
|
|
22
|
+
else
|
|
23
|
+
raise "Not configured!"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def all
|
|
28
|
+
if connected_to_membase?
|
|
29
|
+
key = cache_key(":all")
|
|
30
|
+
connection.local_cache.fetch(key) do
|
|
31
|
+
cached_json = connection.get(resources_name)
|
|
32
|
+
if cached_json.present?
|
|
33
|
+
data = Yajl.load(cached_json)
|
|
34
|
+
validate_against_schema!(:index, data)
|
|
35
|
+
data.map{ |hash| from_hash(hash) }
|
|
36
|
+
else
|
|
37
|
+
[]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
elsif connected_to_admin?
|
|
41
|
+
data = connection.get(resources_name)
|
|
42
|
+
validate_against_schema!(:index, data)
|
|
43
|
+
data.map{ |hash| from_hash(hash) }
|
|
44
|
+
else
|
|
45
|
+
raise "Not configured!"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def create(attrs={})
|
|
50
|
+
@errors = catch :errors do
|
|
51
|
+
return create!(attrs)
|
|
52
|
+
end
|
|
53
|
+
nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def create!(attrs={})
|
|
57
|
+
data = {resource_name => attrs.stringify_keys}
|
|
58
|
+
validate_against_schema!(:create, data)
|
|
59
|
+
data = connection.post("#{resources_name}", data)
|
|
60
|
+
validate_against_schema!(:show, data)
|
|
61
|
+
from_hash(data)
|
|
9
62
|
end
|
|
10
63
|
|
|
11
|
-
def
|
|
12
|
-
|
|
64
|
+
def api=(api)
|
|
65
|
+
@api = api
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def validate=(validate)
|
|
69
|
+
@validate = validate
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
protected
|
|
73
|
+
|
|
74
|
+
ID_PATTERN = /\A\d+\z/.freeze
|
|
75
|
+
def validate_id!(id)
|
|
76
|
+
if validate?
|
|
77
|
+
unless (id.is_a?(Integer) || ID_PATTERN.match(id.to_s)) && id.to_i > 0
|
|
78
|
+
raise "Invalid ID: #{id.inspect}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
UUID_PATTERN = /\A[a-z0-9]+\z/.freeze
|
|
84
|
+
def validate_uuid!(uuid)
|
|
85
|
+
if validate?
|
|
86
|
+
unless UUID_PATTERN.match(uuid) && uuid.length <= 25
|
|
87
|
+
raise "Invalid UUID: #{uuid}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
rescue Exception => e
|
|
91
|
+
raise "Invalid UUID: #{uuid}"
|
|
13
92
|
end
|
|
14
93
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
94
|
+
# schema_name : one of [:index, :show, :create, update]
|
|
95
|
+
# data : the serializable object that should match the given schema
|
|
96
|
+
def validate_against_schema!(schema_name, data)
|
|
97
|
+
if validate? && data.present?
|
|
98
|
+
JSON::Validator.validate!(schema.send(schema_name), data)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def from_hash(hash)
|
|
103
|
+
if hash.present?
|
|
104
|
+
attrs = hash[resource_name]
|
|
105
|
+
klass.new(attrs) if attrs.present?
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def api
|
|
110
|
+
if self.is_a?(Class)
|
|
18
111
|
@api || Neuron::Client::API.default_api
|
|
112
|
+
else
|
|
113
|
+
@api || self.class.api
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def validate?
|
|
118
|
+
return !!@validate unless @validate.nil?
|
|
119
|
+
if self.is_a?(Class)
|
|
120
|
+
api.validate?
|
|
121
|
+
else
|
|
122
|
+
self.class.validate?
|
|
19
123
|
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def connection
|
|
127
|
+
api.connection
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def connected?
|
|
131
|
+
connection.present?
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def connected_to_admin?
|
|
135
|
+
api.connection_type == :admin && connected?
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def connected_to_membase?
|
|
139
|
+
api.connection_type == :membase && connected?
|
|
140
|
+
end
|
|
20
141
|
|
|
21
|
-
|
|
22
|
-
|
|
142
|
+
def connected_to_admin!
|
|
143
|
+
raise("Not configured for admin server!") unless connected_to_admin?
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def connected_to_membase!
|
|
147
|
+
raise("Not configured for membase server!") unless connected_to_membase?
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def klass
|
|
151
|
+
@klass ||= (self.is_a?(Class) ? self : self.class)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def schema
|
|
155
|
+
@schema ||= "Neuron::Schema::#{klass.name.demodulize}::SCHEMA".constantize
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def cache_key(id)
|
|
159
|
+
"#{klass.name.demodulize}:#{id}"
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def resource_name
|
|
163
|
+
@resource_name ||= klass.name.demodulize.underscore
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def resources_name
|
|
167
|
+
@resources_name ||= resource_name.pluralize
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def self.included(base)
|
|
172
|
+
base.send(:attr_accessor, :errors) if base.is_a?(Class)
|
|
173
|
+
base.send(:attr_reader, :id) if base.is_a?(Class)
|
|
174
|
+
base.extend(ClassAndInstanceMethods)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
include ClassAndInstanceMethods
|
|
178
|
+
|
|
179
|
+
def initialize(attrs={})
|
|
180
|
+
apply_attributes!(attrs)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def apply_attributes!(attrs)
|
|
184
|
+
if attrs.present?
|
|
185
|
+
attrs.each do |k,v|
|
|
186
|
+
self.send("#{k}=", v) if self.respond_to?("#{k}=")
|
|
23
187
|
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
24
190
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
191
|
+
def to_hash(*except)
|
|
192
|
+
hash = {}
|
|
193
|
+
except = except.map(&:to_sym)
|
|
194
|
+
attributes.each do |attribute|
|
|
195
|
+
unless except.include?(attribute.to_sym)
|
|
196
|
+
value = send(attribute)
|
|
197
|
+
hash[attribute.to_s] = value
|
|
29
198
|
end
|
|
199
|
+
end
|
|
200
|
+
{resource_name => hash}
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def to_create_hash(*except)
|
|
204
|
+
to_hash(*([:errors, :updated_at, :created_at, :id] + except))
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def to_update_hash(*except)
|
|
208
|
+
to_hash(*([:errors, :updated_at, :created_at] + except))
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def new_record?
|
|
212
|
+
id.nil?
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def id=(id)
|
|
216
|
+
@id = Integer(id)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def save
|
|
220
|
+
update_attributes
|
|
221
|
+
end
|
|
30
222
|
|
|
31
|
-
|
|
32
|
-
|
|
223
|
+
def update_attributes(attrs={})
|
|
224
|
+
connected_to_admin!
|
|
225
|
+
@errors = catch :errors do
|
|
226
|
+
apply_attributes!(attrs) if attrs.present?
|
|
227
|
+
data = {}
|
|
228
|
+
if new_record?
|
|
229
|
+
data = to_create_hash
|
|
230
|
+
validate_against_schema!(:create, data)
|
|
231
|
+
data = connection.post(resources_name, data)
|
|
232
|
+
else
|
|
233
|
+
data = to_update_hash
|
|
234
|
+
validate_against_schema!(:update, data)
|
|
235
|
+
data = connection.put("#{resources_name}/#{id}", data)
|
|
33
236
|
end
|
|
237
|
+
apply_attributes!(data[resource_name])
|
|
238
|
+
[]
|
|
34
239
|
end
|
|
240
|
+
@errors.empty?
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def valid?
|
|
244
|
+
@errors.empty?
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def destroy
|
|
248
|
+
connected_to_admin!
|
|
249
|
+
connection.delete("#{resources_name}/#{id}")
|
|
35
250
|
end
|
|
36
251
|
end
|
|
37
252
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Neuron
|
|
2
|
+
module Client
|
|
3
|
+
class BlockedReferer
|
|
4
|
+
include Base
|
|
5
|
+
|
|
6
|
+
ATTRIBUTES = [
|
|
7
|
+
:id,
|
|
8
|
+
:referer, # string, URL
|
|
9
|
+
:created_at, # string, datetime in UTC
|
|
10
|
+
:updated_at, # string, datetime in UTC
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
attr_accessor *ATTRIBUTES
|
|
14
|
+
|
|
15
|
+
def attributes
|
|
16
|
+
ATTRIBUTES
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Neuron
|
|
2
|
+
module Client
|
|
3
|
+
class BlockedUserAgent
|
|
4
|
+
include Base
|
|
5
|
+
|
|
6
|
+
ATTRIBUTES = [
|
|
7
|
+
:id,
|
|
8
|
+
:user_agent, # string, regex (max 2 GB length)
|
|
9
|
+
:description, # nil, or string (max 2 GB length)
|
|
10
|
+
:created_at, # string, datetime in UTC
|
|
11
|
+
:updated_at, # string, datetime in UTC
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
attr_accessor *ATTRIBUTES
|
|
15
|
+
|
|
16
|
+
def attributes
|
|
17
|
+
ATTRIBUTES
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Neuron
|
|
2
|
+
module Client
|
|
3
|
+
class GeoTarget
|
|
4
|
+
include Base
|
|
5
|
+
|
|
6
|
+
TYPES = %w(COUNTRY REGION METRO CITY) # DO NOT modify, unless you're absolutely sure of all the ramifications!
|
|
7
|
+
|
|
8
|
+
ATTRIBUTES = [
|
|
9
|
+
:id,
|
|
10
|
+
:geo_type, # string, one of TYPES
|
|
11
|
+
:net_acuity_id, # integer
|
|
12
|
+
:abbreviation, # string
|
|
13
|
+
:full_name, # string
|
|
14
|
+
:name, # string
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
attr_accessor *ATTRIBUTES
|
|
18
|
+
|
|
19
|
+
def attributes
|
|
20
|
+
ATTRIBUTES
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
EXPECTED_QUERY_PARAMS = %w(geo_type search limit)
|
|
24
|
+
def self.query(parameters)
|
|
25
|
+
if validate?
|
|
26
|
+
unless parameters.all?{|k,v| EXPECTED_QUERY_PARAMS.include?(k.to_s)}
|
|
27
|
+
raise "Unsupported parameters: #{parameters.inspect}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
data = self.connection.get("geo_targets", parameters)
|
|
31
|
+
validate_against_schema!(:index, data)
|
|
32
|
+
data.map{ |hash| from_hash(hash) }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Neuron
|
|
2
|
+
module Client
|
|
3
|
+
class Pixel
|
|
4
|
+
include Base
|
|
5
|
+
|
|
6
|
+
ATTRIBUTES = [
|
|
7
|
+
:id,
|
|
8
|
+
:ad_ids, # array of integers
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
attr_accessor *ATTRIBUTES
|
|
12
|
+
|
|
13
|
+
def attributes
|
|
14
|
+
ATTRIBUTES
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ad_ids
|
|
18
|
+
@ad_ids.nil? ? [] : @ad_ids
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Neuron
|
|
2
|
+
module Client
|
|
3
|
+
class Report
|
|
4
|
+
include Base
|
|
5
|
+
|
|
6
|
+
TEMPLATES = %w(ad_events delivery_metrics post_activities)
|
|
7
|
+
|
|
8
|
+
STATES = %w(WAITING RUNNING READY FAILED CANCELLED)
|
|
9
|
+
|
|
10
|
+
ATTRIBUTES = [
|
|
11
|
+
:id,
|
|
12
|
+
:parameters, # hash, where keys are parameter names, and values are parameter values as strings.
|
|
13
|
+
:state, # string, one of STATES
|
|
14
|
+
:template, # string, one of TEMPLATES
|
|
15
|
+
:created_at, # string, datetime in UTC
|
|
16
|
+
:updated_at, # string, datetime in UTC
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
attr_accessor *ATTRIBUTES
|
|
20
|
+
|
|
21
|
+
def attributes
|
|
22
|
+
ATTRIBUTES
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def status
|
|
26
|
+
@state
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def result
|
|
30
|
+
connected_to_admin!
|
|
31
|
+
connection.get("reports/#{id}/result", :format => "")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Neuron
|
|
2
|
+
module Client
|
|
3
|
+
class S3File
|
|
4
|
+
include Base
|
|
5
|
+
|
|
6
|
+
PURPOSE_CHOICES = [
|
|
7
|
+
"REPORT_RESULT",
|
|
8
|
+
"RAW_EVENT_LOG",
|
|
9
|
+
"NORMALIZED_EVENT_LOG",
|
|
10
|
+
"ENRICHED_EVENT_LOG"
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
ATTRIBUTES = [
|
|
14
|
+
:id,
|
|
15
|
+
:bucket, # string, at least 3 chars
|
|
16
|
+
:filename, # string
|
|
17
|
+
:filesize, # nil, or integer
|
|
18
|
+
:purpose, # string, one of PURPOSE_CHOICES
|
|
19
|
+
:created_at, # string, datetime in UTC
|
|
20
|
+
:updated_at, # string, datetime in UTC
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
attr_accessor *ATTRIBUTES
|
|
24
|
+
|
|
25
|
+
def attributes
|
|
26
|
+
ATTRIBUTES
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Neuron
|
|
2
|
+
module Client
|
|
3
|
+
class Zone
|
|
4
|
+
include Base
|
|
5
|
+
include ZoneCalculations
|
|
6
|
+
|
|
7
|
+
ADS_BY_PRIORITY_TTL = 60 #seconds
|
|
8
|
+
|
|
9
|
+
REDIRECT = "Redirect"
|
|
10
|
+
IRIS = "Iris"
|
|
11
|
+
VAST = "Vast"
|
|
12
|
+
RESPONSE_TYPES = [REDIRECT, IRIS, VAST]
|
|
13
|
+
|
|
14
|
+
TEMPLATE_SLUGS = ["300x250", "300x600"]
|
|
15
|
+
|
|
16
|
+
ATTRIBUTES = [
|
|
17
|
+
:id,
|
|
18
|
+
:ad_links,
|
|
19
|
+
:name,
|
|
20
|
+
:response_type, # string in RESPONSE_TYPES
|
|
21
|
+
:template_slug, # nil, or string in TEMPLATE_SLUGS
|
|
22
|
+
:mute, # nil, or "Yes" or "No"
|
|
23
|
+
:autoplay, # nil, or "Yes" or "No"
|
|
24
|
+
:channel, # nil, or slug
|
|
25
|
+
:expand, # nil, or "Yes" or "No"
|
|
26
|
+
:text_overlay, # nil, or "Yes" or "No"
|
|
27
|
+
:nami_feed_url, # nil, or string URL
|
|
28
|
+
:created_at, # string, datetime in UTC
|
|
29
|
+
:updated_at, # string, datetime in UTC
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
attr_accessor *ATTRIBUTES
|
|
33
|
+
|
|
34
|
+
def attributes
|
|
35
|
+
ATTRIBUTES
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def id=(id)
|
|
39
|
+
@id = id.to_s
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def find_ad(ad_id)
|
|
43
|
+
Ad.find(ad_id)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def unlink(ad_id)
|
|
47
|
+
connected_to_admin!
|
|
48
|
+
validate_id!(ad_id)
|
|
49
|
+
validate_uuid!(id)
|
|
50
|
+
connection.delete("zones/#{id}/ads/#{ad_id}")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def ads_by_priority
|
|
54
|
+
if connected_to_membase?
|
|
55
|
+
connection.fetch("Zone:#{id}:ads_by_priority", ADS_BY_PRIORITY_TTL) do
|
|
56
|
+
calculate_ads_by_priority
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
calculate_ads_by_priority
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Neuron
|
|
2
|
+
module Client
|
|
3
|
+
module ZoneCalculations
|
|
4
|
+
# This module expects the following methods to be defined:
|
|
5
|
+
#
|
|
6
|
+
# ad_links (Hash, keys are ad IDs, values are a sub-hash: {'priority' => p, 'weight' => w})
|
|
7
|
+
# find_ad(ad_id) (nil, or an object that responds to :active? and :pressure)
|
|
8
|
+
|
|
9
|
+
def ads_by_priority
|
|
10
|
+
calculate_ads_by_priority
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def calculate_ads_by_priority
|
|
14
|
+
entries = {}
|
|
15
|
+
ad_links.each do |ad_id, link|
|
|
16
|
+
next unless ad = find_ad(ad_id)
|
|
17
|
+
next unless ad.active?
|
|
18
|
+
weight = link['weight'].to_f
|
|
19
|
+
priority = link['priority'].to_f
|
|
20
|
+
entries[priority] ||= []
|
|
21
|
+
entries[priority] << [ad_id, weighted_pressure(weight, ad.pressure)]
|
|
22
|
+
end
|
|
23
|
+
entries.sort_by do |priority, entry|
|
|
24
|
+
priority
|
|
25
|
+
end.map do |priority, entry|
|
|
26
|
+
entry.sort_by(&:first)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def weighted_pressure(weight, pressure)
|
|
33
|
+
[( [weight, 0.0].max * [pressure, 1.0].max ), 1.0].max.to_f
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|