snowly 0.2.0 → 0.2.2

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.
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