snowly 0.2.0 → 0.2.2

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
  !binary "U0hBMQ==":
3
- metadata.gz: 9254b6f1c821d30a0c34f25cf92c619935f30c8b
4
- data.tar.gz: bbbcb42cc46d319243ea3fba626dbc1dafdcd313
3
+ metadata.gz: 8363b19687de0fa4f4812b7a6209a2caf414149e
4
+ data.tar.gz: e9b6a30be212eb0f42196f696dc10a6013cad6b0
5
5
  SHA512:
6
- metadata.gz: 3f6d0d38ce02be8812ec8ef1d45d039802debb0df4b1e0c0ae953586b90bf96383ed6a2e12722dbc8811bcc1ec3c9cbe7a9a381b6d07b456720171123cbd31ba
7
- data.tar.gz: 9e63cebeec4c54f429ba8cee65403ad46e36900f7f8638857a11314a8bb14711fc366fa1dfbb6297a7e282fb5ec21d8882d6a8fe74707ebcd18bf12741ffcc48
6
+ metadata.gz: 0e713e4e7f804f8cf715730a9c157cfb4bf6493f019f59658e83752af4fc0d029af70087d8368d59d1c34b6b72757fd1c57d00f6c898d3f54edca56489edbe37
7
+ data.tar.gz: 71423a4271c014abdecd4f4e146cf5a8aaa338a482fd417386dd5a1424e150aa512fee2b113544868d3b9fe582bf35d4380b206b427d7d12b4febc379efc95ed
data/config.ru CHANGED
@@ -3,4 +3,5 @@ require 'bundler'
3
3
  Bundler.setup
4
4
  require 'snowly'
5
5
  require 'snowly/app/collector'
6
- run Snowly::App::Collector
6
+ Snowly.debug_mode = true
7
+ run Snowly::App::Collector
@@ -249,7 +249,7 @@
249
249
  "type": "number"
250
250
  }
251
251
  },
252
- "required": ["app_id", "platform", "event", "event_id", "v_tracker", "useragent"],
252
+ "required": ["app_id", "platform", "event", "event_id", "v_tracker"],
253
253
  "custom_dependencies": {
254
254
  "se_category": { "event": "se" },
255
255
  "se_action": {"event": "se" },
@@ -1,3 +1,4 @@
1
+ require 'thin'
1
2
  require 'erb'
2
3
  require 'base64'
3
4
  require 'sinatra'
@@ -6,44 +7,33 @@ require 'sinatra/reloader' if development?
6
7
  module Snowly
7
8
  module App
8
9
  class Collector < Sinatra::Base
10
+ set :server, 'thin'
9
11
  GIF = Base64.decode64('R0lGODlhAQABAPAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==')
10
12
  configure :development do
11
13
  register Sinatra::Reloader
12
14
  end
13
15
 
14
- def extract_content(validator)
15
- multi = validator.respond_to?(:validators)
16
- @content ||= if multi
17
- validator.validators.each_with_object([]) do |item, memo|
18
- item_request = item.request.as_hash
19
- memo << { event_id: item_request['event_id'], errors: item.errors, content: item_request }
20
- end
21
- else
22
- [{ event_id: validator.request.as_hash['event_id'], errors: validator.errors, content: validator.request.as_hash }]
23
- end.to_json
24
- end
25
-
26
16
  def handle_response(validator)
17
+ content_type :json
27
18
  if validator.validate
28
19
  status 200
29
20
  if params[:debug] || Snowly.debug_mode
30
- content = extract_content validator
21
+ content = validator.as_hash
31
22
  Snowly.logger.info content
32
- body(content)
23
+ body(content.to_json)
33
24
  else
34
25
  content_type 'image/gif'
35
26
  Snowly::App::Collector::GIF
36
27
  end
37
28
  else
38
- status 500
39
- content = extract_content validator
29
+ status 422
30
+ content = validator.as_hash
40
31
  Snowly.logger.error content
41
- body (content)
32
+ body (content.to_json)
42
33
  end
43
34
  end
44
35
 
45
36
  get '/' do
46
- @url = request.url.gsub(/(http|https)\:\/\//,'')[0..-2]
47
37
  @resolved_schemas = if resolver = Snowly.development_iglu_resolver_path
48
38
  Dir[File.join(resolver,"/**/*")].select{ |e| File.file? e }
49
39
  else
@@ -53,18 +43,21 @@ module Snowly
53
43
  end
54
44
 
55
45
  get '/i' do
56
- content_type :json
57
46
  validator = Snowly::Validator.new request.query_string
58
47
  handle_response(validator)
59
48
  end
60
49
 
50
+ get '/js' do
51
+ erb :js
52
+ end
53
+
61
54
  post '/com.snowplowanalytics.snowplow/tp2' do
62
55
  response.headers['Allow'] = 'HEAD,GET,PUT,POST,DELETE,OPTIONS'
63
56
  response.headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Cache-Control, Accept'
64
57
  response.headers['Access-Control-Allow-Credentials'] = 'true'
65
58
  response.headers['Access-Control-Allow-Origin'] = env['HTTP_ORIGIN'] || '*'
66
59
  payload = JSON.parse request.body.read
67
- validator = Snowly::MultiValidator.new payload
60
+ validator = Snowly::Validator.new payload, batch: true
68
61
  handle_response(validator)
69
62
  end
70
63
 
@@ -22,7 +22,7 @@
22
22
  <p><strong>Snowly</strong> is a minimal collector implementation intended to validate your event tracking requests before emitting them to cloudfront or a closure collector.</p>
23
23
  <p>When <strong>Snowly</strong> finds something wrong, it renders the parsed request along with its errors.</p>
24
24
  <p>If everything is ok, Snowly delivers the default Snowplow pixel, unless you're using the debug mode.</p>
25
- <p>Point your collector URL to <code><%= url %></code> and have fun!</p>
25
+ <p>Point your collector URL to <code><%= request.env['HTTP_HOST'] %></code> and have fun!</p>
26
26
  <p>
27
27
  <a class="btn btn-lg btn-success" href="/i?&e=pv&page=Root%20README&url=http%3A%2F%2Fgithub.com%2Fsnowplow%2Fsnowplow&aid=snowplow&p=web&tv=no-js-0.1.0&ua=firefox&&eid=u2i3&debug=true" role="button">See it working!</a>
28
28
  <a class="btn btn-lg btn-warning" href="/i?&e=pv&page=Root%20README&url=http%3A%2F%2Fgithub.com%2Fsnowplow%2Fsnowplow&aid=snowplow&p=i&tv=no-js-0.1.0&eid=u2i3&debug=true" role="button">Event with errors!</a>
@@ -0,0 +1,153 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2
+ "http://www.w3.org/TR/html4/loose.dtd">
3
+ <!--
4
+ ! Copyright (c) 2012-2013 Snowplow Analytics Ltd. All rights reserved.
5
+ !
6
+ ! This program is licensed to you under the Apache License Version 2.0,
7
+ ! and you may not use this file except in compliance with the Apache License Version 2.0.
8
+ ! You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
9
+ !
10
+ ! Unless required by applicable law or agreed to in writing,
11
+ ! software distributed under the Apache License Version 2.0 is distributed on an
12
+ ! "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ ! See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
14
+ -->
15
+ <html>
16
+ <head>
17
+ <title>Small asynchronous website/webapp examples for snowplow.js</title>
18
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
19
+
20
+ <!-- Snowplow starts plowing -->
21
+ <script type="text/javascript">
22
+
23
+ ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[];
24
+ p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments)
25
+ };p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
26
+ n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","//d1fc8wv8zag5ca.cloudfront.net/2.6.1/sp.js","snowplow"));
27
+
28
+ window.snowplow('newTracker', 'cf', '<%= request.env['HTTP_HOST']%>', { // Initialise a tracker
29
+ encodeBase64: false, // Default is true
30
+ appId: 'CFe23a', // Site ID can be anything you want. Set it if you're tracking more than one site in this account
31
+ platform: 'mob',
32
+ useLocalStorage: false,
33
+ post: true,
34
+ forceUnsecureTracker: true,
35
+ contexts: {
36
+ webPage: true,
37
+ gaCookies: true,
38
+ performanceTiming: true
39
+ }
40
+ });
41
+
42
+ window.snowplow('setUserId', 'alex 123'); // Business-defined user ID
43
+ //window.snowplow('setUserIdFromLocation', 'id'); // To test this, reload the page with ?id=xxx
44
+ //window.snowplow('setUserIdFromCookie', '_sp_id.4209') // Test this using Firefox because Chrome doesn't allow local cookies.
45
+ window.snowplow('setCustomUrl', '/overridden-url/'); // Override the page URL
46
+ // window.snowplow('enableActivityTracking', 10, 10); // Ping every 10 seconds after 10 seconds
47
+ window.snowplow('enableLinkClickTracking', {blacklist: ['barred']}, true); // Track clicks on links whose class is not "barred"
48
+ window.snowplow('trackPageView', 'Async Test'); // Track the page view with custom title
49
+
50
+ </script>
51
+ <!-- Snowplow stops plowing -->
52
+
53
+ <!-- Example events -->
54
+ <script type="text/javascript">
55
+
56
+ function playMix() {
57
+ alert("Playing a DJ mix");
58
+ window.snowplow('trackStructEvent', 'Mixes', 'Play', 'MRC/fabric-0503-mix', '', '0.0');
59
+ }
60
+
61
+ function addProduct() {
62
+ alert("Adding a product to basket");
63
+ window.snowplow('trackStructEvent', 'Checkout', 'Add', 'ASO01043', 'blue:xxl', '2.0' );
64
+ }
65
+
66
+ function wrongAddProduct() {
67
+ alert("Adding a product to basket");
68
+ window.snowplow('trackStructEvent', '', 'Add', 'ASO01043', 'blue:xxl', '2.0' );
69
+ }
70
+
71
+ function viewProduct() {
72
+ alert("Viewing a product");
73
+ window.snowplow('trackUnstructEvent', {
74
+ schema: 'iglu:com.acme_company/viewed_product/jsonschema/5-0-0',
75
+ data: {
76
+ productId: 'ASO01043',
77
+ category: 'Dresses',
78
+ brand: 'ACME',
79
+ returning: true,
80
+ price: 49.95,
81
+ sizes: ['xs', 's', 'l', 'xl', 'xxl'],
82
+ availableSince: new Date(2013,3,7)
83
+ }
84
+ });
85
+ }
86
+
87
+ function addEcommerceTransaction() {
88
+ alert('Adding an ecommerce transaction');
89
+
90
+ var orderId = 'order-123';
91
+
92
+ // addTrans sets up the transaction, should be called first.
93
+ window.snowplow('addTrans',
94
+ orderId, // order ID - required
95
+ '', // affiliation or store name
96
+ '8000', // total - required
97
+ '', // tax
98
+ '', // shipping
99
+ '', // city
100
+ '', // state or province
101
+ '', // country
102
+ 'JPY' // currency
103
+ );
104
+
105
+ // addItem might be called for each item in the shopping cart,
106
+ // or not at all.
107
+ window.snowplow('addItem',
108
+ orderId, // order ID - required
109
+ '1001', // SKU - required
110
+ 'Blue t-shirt', // product name
111
+ '', // category
112
+ '2000', // unit price - required
113
+ '2', // quantity - required
114
+ 'JPY');
115
+
116
+ window.snowplow('addItem',
117
+ orderId, // order ID - required
118
+ '1002', // SKU - required
119
+ 'Red shoes', // product name
120
+ '', // category
121
+ '4000', // unit price - required
122
+ '1', // quantity - required
123
+ 'JPY' // currency
124
+ );
125
+
126
+ // trackTrans sends the transaction to Snowplow tracking servers.
127
+ // Must be called last to commit the transaction.
128
+ window.snowplow('trackTrans');
129
+
130
+ }
131
+ </script>
132
+ </head>
133
+
134
+ <body>
135
+ <h1>Small_asynchronous_examples_for_snowplow.js</h1>
136
+
137
+ <p>Warning: if your browser's Do Not Track feature is enabled and respectDoNotTrack is enabled, all tracking will be prevented.</p>
138
+ <p>If you are viewing the page using a file URL, you must edit the script URL in the Snowplow tag to include an http scheme. Otherwise a file scheme will be inferred and the page will attempt to load sp.js from the local filesystem..</p>
139
+
140
+ <p>Press the buttons below to trigger individual tracking events:<br>
141
+ <button type="button" onclick="playMix()">Play a mix</button><br>
142
+ <button type="button" onclick="addProduct()">Add a product</button><br>
143
+ <button type="button" onclick="wrongAddProduct()">Add a product missing required field</button><br>
144
+ <button type="button" onclick="viewProduct()">View a product</button><br>
145
+ <button type="button" onclick="addEcommerceTransaction()">Add an ecommerce transaction</button>
146
+ </p>
147
+ <a href=http://en.wikipedia.org/wiki/Main_Page id=legal target="_blank" class="link out">Link</a>
148
+ <br>
149
+ <a href=http://en.wikipedia.org/wiki/Main_Page id=illegal class="class barred">Ignored link</a>
150
+
151
+ </body>
152
+
153
+ </html>
@@ -0,0 +1,109 @@
1
+ # Performs the validation for the root attributes and associated contexts and unstructured events.
2
+ require 'snowly/request'
3
+ require 'snowly/protocol_schema_finder'
4
+ require 'snowly/extensions/custom_dependencies'
5
+
6
+ module Snowly
7
+ class EachValidator
8
+ attr_reader :request, :errors
9
+
10
+ def initialize(payload)
11
+ @request = Request.new payload
12
+ @errors = []
13
+ end
14
+
15
+ # If request is valid
16
+ # @return [true, false] if valid
17
+ def valid?
18
+ @errors == []
19
+ end
20
+
21
+ # Entry point for validation.
22
+ def validate
23
+ validate_root
24
+ validate_associated
25
+ valid?
26
+ end
27
+
28
+ def protocol_schema
29
+ @protocol_schema ||= ProtocolSchemaFinder.new.schema
30
+ end
31
+
32
+ def as_hash
33
+ { event_id: request.as_hash['event_id'], errors: errors, content: request.as_hash }
34
+ end
35
+
36
+ private
37
+
38
+ # @return [Hash] all contexts content and schema definitions
39
+ def associated_contexts
40
+ load_contexts request.as_hash['contexts']
41
+ end
42
+
43
+ # @return [Hash] all unstructured events content and schema definitions
44
+ def associated_unstruct_event
45
+ load_unstruct_event request.as_hash['unstruct_event']
46
+ end
47
+
48
+ # @return [Array<Hash>] all associated content
49
+ def associated_elements
50
+ (Array(associated_contexts) + Array(associated_unstruct_event)).compact
51
+ end
52
+
53
+ # Performs initial validation for associated contexts and loads their contents and definitions.
54
+ # @return [Array<Hash>]
55
+ def load_contexts(hash)
56
+ return unless hash
57
+ response = []
58
+ unless hash['data']
59
+ @errors << "All custom contexts must be contain a `data` element" and return
60
+ end
61
+ schema = SchemaCache.instance[hash['schema']]
62
+ response << { content: hash['data'], definition: schema, schema_name: hash['schema'] }
63
+ unless hash['data'].is_a? Array
64
+ @errors << "All custom contexts must be wrapped in an Array" and return
65
+ end
66
+ hash['data'].each do |data_item|
67
+ schema = SchemaCache.instance[data_item['schema']]
68
+ response << { content: data_item['data'], definition: schema, schema_name: data_item['schema'] }
69
+ end
70
+ response
71
+ end
72
+
73
+ def register_missing_schema(name)
74
+ @errors << "#{ name } wasn't found in any resolvers."
75
+ end
76
+
77
+ # Performs initial validation for associated unstructured events and loads their contents and definitions.
78
+ # @return [Array<Hash>]
79
+ def load_unstruct_event(hash)
80
+ return unless hash
81
+ response = []
82
+ unless hash['data']
83
+ @errors << "All custom unstruct event must be contain a `data` element" and return
84
+ end
85
+ outer_data = hash['data']
86
+ inner_data = outer_data['data']
87
+ response << { content: outer_data, definition: SchemaCache.instance[hash['schema']], schema_name: hash['schema'] }
88
+ response << { content: inner_data, definition: SchemaCache.instance[outer_data['schema']], schema_name: outer_data['schema'] }
89
+ response
90
+ end
91
+
92
+ # Validates associated contexts and unstructured events
93
+ def validate_associated
94
+ return unless associated_elements
95
+ missing_schemas, valid_elements = associated_elements.partition{ |el| el[:definition].blank? }
96
+ missing_schemas.each { |element| register_missing_schema(element[:schema_name]) }
97
+ valid_elements.each do |element|
98
+ this_error = JSON::Validator.fully_validate JSON.parse(element[:definition]), element[:content]
99
+ @errors += this_error if this_error.count > 0
100
+ end
101
+ end
102
+
103
+ # Validates root attributes for the events table
104
+ def validate_root
105
+ this_error = JSON::Validator.fully_validate protocol_schema, request.as_hash
106
+ @errors += this_error if this_error.count > 0
107
+ end
108
+ end
109
+ end
@@ -26,13 +26,6 @@ module Snowly
26
26
 
27
27
  private
28
28
 
29
- # If schema should be resolved to snowplow iglu server
30
- # @param location [String]
31
- # @return [true, false]
32
- def from_snowplow?(location)
33
- location['iglu:com.snowplowanalytics.snowplow']
34
- end
35
-
36
29
  def external?(location)
37
30
  location.match(/^(http|https):\/\//)
38
31
  end
@@ -42,25 +35,29 @@ module Snowly
42
35
  # @param resolver [String] local or remote path to look for the schema
43
36
  # @return [String] Schema's actual location
44
37
  def resolve(location, resolver)
45
- location.sub(/^iglu\:/, resolver)
46
- end
47
-
48
- def resolved_path(location)
49
- if from_snowplow?(location)
50
- resolve(location, SNOWPLOW_IGLU_RESOLVER)
51
- else
52
- resolve(location, Snowly.development_iglu_resolver_path)
53
- end
38
+ path = location.sub(/^iglu\:/, '')
39
+ File.join resolver, path
54
40
  end
55
41
 
56
42
  # Caches the schema content under its original location name
57
43
  # @param location [String]
58
44
  # @return [String] schema content
59
45
  def save_in_cache(location)
60
- full_path = resolved_path(location)
61
- content = external?(full_path) ? Net::HTTP.get(URI(full_path)) : File.read(full_path)
46
+ content = begin
47
+ full_path = resolve(location, (Snowly.development_iglu_resolver_path || SNOWPLOW_IGLU_RESOLVER) )
48
+ external?(full_path) ? Net::HTTP.get(URI(full_path)) : File.read(full_path)
49
+ rescue
50
+ Snowly.logger.warn "Could't locate #{location} in development resolver. Attemping IgluCentral Server..."
51
+ full_path = resolve(location, SNOWPLOW_IGLU_RESOLVER)
52
+ begin
53
+ result = Net::HTTP.get(URI(full_path))
54
+ JSON.load(result) && result
55
+ rescue
56
+ Snowly.logger.error "#{location} schema is not available in any resolver"
57
+ return nil
58
+ end
59
+ end
62
60
  @@schema_cache[location] = content
63
61
  end
64
-
65
62
  end
66
63
  end
@@ -35,7 +35,7 @@ module Snowly
35
35
  "f_ag" => { field: "br_features_silverlight", type: "string" },
36
36
  "cookie" => { field: "br_cookies", type: "string" },
37
37
  "res" => { field: "screen_res_width_x_height", type: "string" },
38
- "cd" => { field: "br_colordepth", type: "string" },
38
+ "cd" => { field: "br_colordepth", type: "integer" },
39
39
  "tz" => { field: "os_timezone", type: "string" },
40
40
  "refr" => { field: "page_referrer", type: "string" },
41
41
  "url" => { field: "page_url", type: "string" },
@@ -1,97 +1,29 @@
1
- # Performs the validation for the root attributes and associated contexts and unstructured events.
2
- require 'snowly/request'
3
- require 'snowly/protocol_schema_finder'
4
- require 'snowly/extensions/custom_dependencies'
5
-
1
+ require 'snowly/each_validator'
6
2
  module Snowly
7
3
  class Validator
8
- attr_reader :request, :errors
9
-
10
- def initialize(payload)
11
- @request = Request.new payload
12
- @errors = []
13
- end
14
-
15
- # If request is valid
16
- # @return [true, false] if valid
17
- def valid?
18
- @errors == []
4
+ attr_reader :validators
5
+
6
+ def initialize(payload, batch: false)
7
+ @validators = if batch
8
+ payload['data'].map do |req|
9
+ EachValidator.new(req)
10
+ end
11
+ else
12
+ [ EachValidator.new(payload) ]
13
+ end
19
14
  end
20
15
 
21
- # Entry point for validation.
22
16
  def validate
23
- validate_root
24
- validate_associated
17
+ validators.each(&:validate)
25
18
  valid?
26
19
  end
27
20
 
28
- def protocol_schema
29
- @protocol_schema ||= ProtocolSchemaFinder.new.schema
30
- end
31
-
32
- private
33
-
34
- # @return [Hash] all contexts content and schema definitions
35
- def associated_contexts
36
- load_contexts request.as_hash['contexts']
37
- end
38
-
39
- # @return [Hash] all unstructured events content and schema definitions
40
- def associated_unstruct_event
41
- load_unstruct_event request.as_hash['unstruct_event']
42
- end
43
-
44
- # @return [Array<Hash>] all associated content
45
- def associated_elements
46
- (Array(associated_contexts) + Array(associated_unstruct_event)).compact
47
- end
48
-
49
- # Performs initial validation for associated contexts and loads their contents and definitions.
50
- # @return [Array<Hash>]
51
- def load_contexts(hash)
52
- return unless hash
53
- response = []
54
- unless hash['data']
55
- @errors << "All custom contexts must be contain a `data` element" and return
56
- end
57
- response << { content: hash['data'], definition: SchemaCache.instance[hash['schema']] }
58
- unless hash['data'].is_a? Array
59
- @errors << "All custom contexts must be wrapped in an Array" and return
60
- end
61
- hash['data'].each do |data_item|
62
- response << { content: data_item['data'], definition: SchemaCache.instance[data_item['schema']] }
63
- end
64
- response
65
- end
66
-
67
- # Performs initial validation for associated unstructured events and loads their contents and definitions.
68
- # @return [Array<Hash>]
69
- def load_unstruct_event(hash)
70
- return unless hash
71
- response = []
72
- unless hash['data']
73
- @errors << "All custom unstruct event must be contain a `data` element" and return
74
- end
75
- outer_data = hash['data']
76
- inner_data = outer_data['data']
77
- response << { content: outer_data, definition: SchemaCache.instance[hash['schema']] }
78
- response << { content: inner_data, definition: SchemaCache.instance[outer_data['schema']] }
79
- response
80
- end
81
-
82
- # Validates associated contexts and unstructured events
83
- def validate_associated
84
- return unless associated_elements
85
- associated_elements.each do |schema|
86
- this_error = JSON::Validator.fully_validate JSON.parse(schema[:definition]), schema[:content]
87
- @errors += this_error if this_error.count > 0
88
- end
21
+ def valid?
22
+ validators.all? { |v| v.valid? }
89
23
  end
90
24
 
91
- # Validates root attributes for the events table
92
- def validate_root
93
- this_error = JSON::Validator.fully_validate protocol_schema, request.as_hash
94
- @errors += this_error if this_error.count > 0
25
+ def as_hash
26
+ validators.map(&:as_hash)
95
27
  end
96
28
  end
97
29
  end
@@ -1,3 +1,3 @@
1
1
  module Snowly
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.2"
3
3
  end
data/lib/snowly.rb CHANGED
@@ -5,8 +5,8 @@ require 'rack'
5
5
  require 'json-schema'
6
6
  require 'snowly/validators/self_desc'
7
7
  require "snowly/version"
8
+ require 'snowly/each_validator'
8
9
  require 'snowly/validator'
9
- require 'snowly/multi_validator'
10
10
  require 'snowly/schema_cache'
11
11
 
12
12
  module Snowly
data/snowly.gemspec CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency 'sinatra', '~> 1.4'
27
27
  spec.add_dependency 'sinatra-contrib', '~> 1.4'
28
28
  spec.add_dependency 'vegas', '~> 0.1'
29
+ spec.add_dependency 'thin', '~> 1.7'
29
30
 
30
31
  spec.add_development_dependency 'bundler', '~> 1.11'
31
32
  spec.add_development_dependency 'rake', '~> 10.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snowly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre Angelim
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-17 00:00:00.000000000 Z
11
+ date: 2016-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json-schema
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: thin
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '1.7'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '1.7'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: bundler
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -215,8 +229,9 @@ files:
215
229
  - lib/snowly.rb
216
230
  - lib/snowly/app/collector.rb
217
231
  - lib/snowly/app/views/index.erb
232
+ - lib/snowly/app/views/js.erb
233
+ - lib/snowly/each_validator.rb
218
234
  - lib/snowly/extensions/custom_dependencies.rb
219
- - lib/snowly/multi_validator.rb
220
235
  - lib/snowly/protocol_schema_finder.rb
221
236
  - lib/snowly/request.rb
222
237
  - lib/snowly/schema_cache.rb
@@ -1,21 +0,0 @@
1
- require 'snowly/validator'
2
- module Snowly
3
- class MultiValidator
4
- attr_reader :validators
5
-
6
- def initialize(payload)
7
- @validators = payload['data'].map do |req|
8
- Validator.new(req)
9
- end
10
- end
11
-
12
- def validate
13
- validators.each(&:validate)
14
- valid?
15
- end
16
-
17
- def valid?
18
- validators.all? { |v| v.valid? }
19
- end
20
- end
21
- end