pupa 0.2.2 → 0.2.3
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 +4 -4
- data/lib/pupa/models/model.rb +10 -5
- data/lib/pupa/processor/client.rb +19 -2
- data/lib/pupa/processor.rb +3 -2
- data/lib/pupa/runner.rb +5 -0
- data/lib/pupa/version.rb +1 -1
- data/lib/pupa.rb +19 -0
- data/spec/refinements/json-schema_spec.rb +2 -1
- metadata +3 -3
- data/lib/pupa/refinements/json-schema.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0b3361fdbe89fad7482ffc7661a04f6a610351e
|
4
|
+
data.tar.gz: 49066676fd5b7519c300eb9e3dfc05655bb6d864
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97f44c06bae5f107264135b2fb82a84fc17cf9ac521903e75fd4653c1a975bc5516f8f33711be9e9d1063a2be1178e728a1ff83752554074b32d895172c768d8
|
7
|
+
data.tar.gz: 330535ef6392fb0990a28ca8e0b30e0ce217ab68407d4afdf7f917a65d0fc8349b1a953547b5be7158f372c85aefd611c7d4e1e480f8d287f63195b3b09cdc82
|
data/lib/pupa/models/model.rb
CHANGED
@@ -6,10 +6,6 @@ require 'active_support/callbacks'
|
|
6
6
|
require 'active_support/core_ext/object/try'
|
7
7
|
require 'json-schema'
|
8
8
|
|
9
|
-
require 'pupa/refinements/json-schema'
|
10
|
-
|
11
|
-
JSON::Validator.cache_schemas = true
|
12
|
-
|
13
9
|
module Pupa
|
14
10
|
# Adds methods expected by Pupa processors.
|
15
11
|
module Model
|
@@ -22,6 +18,7 @@ module Pupa
|
|
22
18
|
define_callbacks :create, :save
|
23
19
|
|
24
20
|
class_attribute :json_schema
|
21
|
+
class_attribute :validator
|
25
22
|
class_attribute :properties
|
26
23
|
class_attribute :foreign_keys
|
27
24
|
class_attribute :foreign_objects
|
@@ -88,6 +85,11 @@ module Pupa
|
|
88
85
|
else
|
89
86
|
JSON.load(File.read(File.expand_path(File.join('..', '..', '..', 'schemas', "#{value}.json"), __dir__)))
|
90
87
|
end
|
88
|
+
|
89
|
+
self.validator = JSON::Validator.new(self.json_schema, {}, {
|
90
|
+
clear_cache: false,
|
91
|
+
parse_data: false,
|
92
|
+
})
|
91
93
|
end
|
92
94
|
end
|
93
95
|
|
@@ -169,7 +171,10 @@ module Pupa
|
|
169
171
|
# @raises [JSON::Schema::ValidationError] if the object is invalid
|
170
172
|
def validate!
|
171
173
|
if self.class.json_schema
|
172
|
-
|
174
|
+
self.class.validator.instance_variable_set('@errors', [])
|
175
|
+
self.class.validator.instance_variable_set('@data', stringify_keys(to_h(persist: true)))
|
176
|
+
self.class.validator.validate
|
177
|
+
true
|
173
178
|
end
|
174
179
|
end
|
175
180
|
|
@@ -14,6 +14,12 @@ rescue LoadError
|
|
14
14
|
# pass
|
15
15
|
end
|
16
16
|
|
17
|
+
begin
|
18
|
+
require 'faraday-cookie_jar'
|
19
|
+
rescue LoadError
|
20
|
+
# pass
|
21
|
+
end
|
22
|
+
|
17
23
|
module Pupa
|
18
24
|
class Processor
|
19
25
|
# An HTTP client factory.
|
@@ -32,9 +38,12 @@ module Pupa
|
|
32
38
|
# @param [String] memcached_password the Memcached password
|
33
39
|
# @param [String] level the log level
|
34
40
|
# @param [String,IO] logdev the log device
|
41
|
+
# @param [Hash] faraday_options Faraday initialization options
|
35
42
|
# @return [Faraday::Connection] a configured Faraday HTTP client
|
36
|
-
def self.new(cache_dir: nil, expires_in: 86400, value_max_bytes: 1048576, memcached_username: nil, memcached_password: nil, level: 'INFO', logdev: STDOUT) # 1 day
|
37
|
-
|
43
|
+
def self.new(cache_dir: nil, expires_in: 86400, value_max_bytes: 1048576, memcached_username: nil, memcached_password: nil, level: 'INFO', logdev: STDOUT, faraday_options: {}) # 1 day
|
44
|
+
follow_redirects = faraday_options.delete(:follow_redirects)
|
45
|
+
|
46
|
+
Faraday.new(faraday_options) do |connection|
|
38
47
|
connection.request :url_encoded
|
39
48
|
connection.use Middleware::Logger, Logger.new('faraday', level: level)
|
40
49
|
connection.use Faraday::Response::RaiseError
|
@@ -53,6 +62,14 @@ module Pupa
|
|
53
62
|
connection.use FaradayMiddleware::ParseXml, preserve_raw: true, content_type: /\bxml$/
|
54
63
|
end
|
55
64
|
|
65
|
+
if follow_redirects
|
66
|
+
connection.use FaradayMiddleware::FollowRedirects, follow_redirects
|
67
|
+
end
|
68
|
+
|
69
|
+
if Faraday.const_defined?('CookieJar')
|
70
|
+
connection.use Faraday::CookieJar
|
71
|
+
end
|
72
|
+
|
56
73
|
# Must come after the parser middlewares.
|
57
74
|
connection.use FaradayMiddleware::Gzip
|
58
75
|
|
data/lib/pupa/processor.rb
CHANGED
@@ -31,10 +31,11 @@ module Pupa
|
|
31
31
|
# @param [Boolean] validate whether to validate JSON documents
|
32
32
|
# @param [String] level the log level
|
33
33
|
# @param [String,IO] logdev the log device
|
34
|
+
# @param [Hash] faraday_options Faraday initialization options
|
34
35
|
# @param [Hash] options criteria for selecting the methods to run
|
35
|
-
def initialize(output_dir, pipelined: false, cache_dir: nil, expires_in: 86400, value_max_bytes: 1048576, memcached_username: nil, memcached_password: nil, database_url: 'mongodb://localhost:27017/pupa', validate: true, level: 'INFO', logdev: STDOUT, options: {})
|
36
|
+
def initialize(output_dir, pipelined: false, cache_dir: nil, expires_in: 86400, value_max_bytes: 1048576, memcached_username: nil, memcached_password: nil, database_url: 'mongodb://localhost:27017/pupa', validate: true, level: 'INFO', logdev: STDOUT, faraday_options: {}, options: {})
|
36
37
|
@store = DocumentStore.new(output_dir, pipelined: pipelined)
|
37
|
-
@client = Client.new(cache_dir: cache_dir, expires_in: expires_in, value_max_bytes: value_max_bytes, memcached_username: memcached_username, memcached_password: memcached_password, level: level, logdev: logdev)
|
38
|
+
@client = Client.new(cache_dir: cache_dir, expires_in: expires_in, value_max_bytes: value_max_bytes, memcached_username: memcached_username, memcached_password: memcached_password, level: level, logdev: logdev, faraday_options: faraday_options)
|
38
39
|
@connection = Connection.new(database_url)
|
39
40
|
@logger = Logger.new('pupa', level: level, logdev: logdev)
|
40
41
|
@validate = validate
|
data/lib/pupa/runner.rb
CHANGED
@@ -23,6 +23,7 @@ module Pupa
|
|
23
23
|
database_url: 'mongodb://localhost:27017/pupa',
|
24
24
|
validate: true,
|
25
25
|
level: 'INFO',
|
26
|
+
faraday_options: {},
|
26
27
|
dry_run: false,
|
27
28
|
}.merge(defaults))
|
28
29
|
|
@@ -82,6 +83,9 @@ module Pupa
|
|
82
83
|
opts.on('-c', '--cache_dir PATH', 'The directory or Memcached address (e.g. memcached://localhost:11211) in which to cache HTTP requests') do |v|
|
83
84
|
options.cache_dir = v
|
84
85
|
end
|
86
|
+
opts.on('--no-cache', 'Disable HTTP request caching') do |v|
|
87
|
+
options.cache_dir = nil
|
88
|
+
end
|
85
89
|
opts.on('-e', '--expires_in SECONDS', "The cache's expiration time in seconds") do |v|
|
86
90
|
options.expires_in = v
|
87
91
|
end
|
@@ -160,6 +164,7 @@ module Pupa
|
|
160
164
|
database_url: options.database_url,
|
161
165
|
validate: options.validate,
|
162
166
|
level: options.level,
|
167
|
+
faraday_options: options.faraday_options,
|
163
168
|
options: Hash[*rest])
|
164
169
|
|
165
170
|
options.actions.each do |action|
|
data/lib/pupa/version.rb
CHANGED
data/lib/pupa.rb
CHANGED
@@ -8,6 +8,8 @@ require 'active_support/core_ext/hash/slice'
|
|
8
8
|
require 'active_support/core_ext/object/blank'
|
9
9
|
require 'active_support/inflector'
|
10
10
|
|
11
|
+
require 'mail'
|
12
|
+
|
11
13
|
require 'pupa/models/concerns/indifferent_access'
|
12
14
|
require 'pupa/models/concerns/contactable'
|
13
15
|
require 'pupa/models/concerns/identifiable'
|
@@ -65,3 +67,20 @@ class String
|
|
65
67
|
# @see http://api.rubyonrails.org/classes/String.html#method-i-blank-3F
|
66
68
|
alias_method :blank?, :empty?
|
67
69
|
end
|
70
|
+
|
71
|
+
# @see https://github.com/ruby-json-schema/json-schema/tree/master/lib/json-schema/attributes/formats
|
72
|
+
JSON::Validator.register_format_validator('email', lambda{|data|
|
73
|
+
return unless data.is_a?(String)
|
74
|
+
address = Mail::Address.new(data)
|
75
|
+
unless address.address == data && address.domain && address.domain.split('.').size > 1
|
76
|
+
raise JSON::Schema::CustomFormatError.new("must be a valid email address (#{data})")
|
77
|
+
end
|
78
|
+
})
|
79
|
+
|
80
|
+
JSON::Validator.register_format_validator('uri', lambda{|data|
|
81
|
+
return unless data.is_a?(String)
|
82
|
+
re = URI::DEFAULT_PARSER.regexp[:ABS_URI]
|
83
|
+
unless re.match(data)
|
84
|
+
raise JSON::Schema::CustomFormatError.new("must be a valid email URI (#{data})")
|
85
|
+
end
|
86
|
+
})
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe JSON::Validator do
|
4
4
|
let(:schema) do
|
5
5
|
{
|
6
|
+
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
6
7
|
'properties' => {
|
7
8
|
'email' => {
|
8
9
|
'type' => ['string', 'null'],
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pupa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James McKinney
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -329,7 +329,6 @@ files:
|
|
329
329
|
- lib/pupa/processor/yielder.rb
|
330
330
|
- lib/pupa/refinements/faraday.rb
|
331
331
|
- lib/pupa/refinements/faraday_middleware.rb
|
332
|
-
- lib/pupa/refinements/json-schema.rb
|
333
332
|
- lib/pupa/runner.rb
|
334
333
|
- lib/pupa/version.rb
|
335
334
|
- pupa.gemspec
|
@@ -452,3 +451,4 @@ test_files:
|
|
452
451
|
- spec/runner_spec.rb
|
453
452
|
- spec/spec_helper.rb
|
454
453
|
- spec/support/shared_examples_for_connection_adapters.rb
|
454
|
+
has_rdoc:
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'mail'
|
2
|
-
|
3
|
-
module Pupa
|
4
|
-
module Refinements
|
5
|
-
# Validates "email" and "uri" formats. Using Ruby's refinements doesn't seem
|
6
|
-
# to work, possibly because `refine` can't be used with `prepend`.
|
7
|
-
module FormatAttribute
|
8
|
-
# @see http://my.rails-royce.org/2010/07/21/email-validation-in-ruby-on-rails-without-regexp/
|
9
|
-
def validate(current_schema, data, fragments, processor, validator, options = {})
|
10
|
-
case current_schema.schema['format']
|
11
|
-
when 'email'
|
12
|
-
if String === data
|
13
|
-
address = Mail::Address.new(data)
|
14
|
-
unless address.address == data && address.domain && address.domain.split('.').size > 1
|
15
|
-
error_message = "The property '#{build_fragment(fragments)}' must be a valid email address (#{data})"
|
16
|
-
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
17
|
-
end
|
18
|
-
else
|
19
|
-
error_message = "The property '#{build_fragment(fragments)}' must be a string (#{data})"
|
20
|
-
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
21
|
-
end
|
22
|
-
when 'uri'
|
23
|
-
if String === data
|
24
|
-
re = URI::DEFAULT_PARSER.regexp[:ABS_URI]
|
25
|
-
unless re.match(data)
|
26
|
-
error_message = "The property '#{build_fragment(fragments)}' must be a valid URI (#{data})"
|
27
|
-
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
28
|
-
end
|
29
|
-
else
|
30
|
-
error_message = "The property '#{build_fragment(fragments)}' must be string (#{data})"
|
31
|
-
validation_error(processor, error_message, fragments, current_schema, self, options[:record_errors])
|
32
|
-
end
|
33
|
-
else
|
34
|
-
super
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
class JSON::Schema::FormatAttribute
|
42
|
-
class << self
|
43
|
-
prepend Pupa::Refinements::FormatAttribute
|
44
|
-
end
|
45
|
-
end
|