Skip to content

Commit

Permalink
Merge 2aa92db into 1bef8dc
Browse files Browse the repository at this point in the history
  • Loading branch information
georgiana-b committed Aug 6, 2017
2 parents 1bef8dc + 2aa92db commit 9c2d8c6
Show file tree
Hide file tree
Showing 13 changed files with 2,533 additions and 151 deletions.
1 change: 1 addition & 0 deletions lib/datapackage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
require 'ruby_dig'
require 'tableschema'

require 'datapackage/defaults'
require 'datapackage/helpers'
require 'datapackage/version'
require 'datapackage/exceptions'
Expand Down
27 changes: 27 additions & 0 deletions lib/datapackage/defaults.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module DataPackage
DEFAULTS = {
resource: {
profile: 'data-resource',
tabular_profile: 'tabular-data-resource',
encoding: 'utf-8',
},
package: {
profile: 'data-package',
},
schema: {
format: 'default',
type: 'string',
missing_values: [''],
},
dialect: {
delimiter: ',',
doubleQuote: true,
lineTerminator: '\r\n',
quoteChar: '"',
escapeChar: '\\',
skipInitialSpace: true,
header: true,
caseSensitiveHeader: false,
},
}.freeze
end
6 changes: 3 additions & 3 deletions lib/datapackage/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ def join_paths(base_path, resource)
if base_path.nil? || base_path.empty?
resource
elsif base_path =~ /\A#{URI::regexp}\z/
URI.join(base_path, resource)
URI.join(base_path, resource).to_s
elsif File.directory?(base_path)
File.join(base_path, resource)
File.join(base_path, resource).to_s
elsif File.file?(base_path)
base_path
else
Expand All @@ -90,7 +90,7 @@ def is_fully_qualified_url?(string)
def is_safe_path?(string)
path = Pathname.new(string)
return false if path.absolute?
return false unless /^\.+$/.match(path.split[0].to_s).nil?
return false unless /^\.+$/.match(path.to_s.split('/').first).nil?
true
end

Expand Down
11 changes: 5 additions & 6 deletions lib/datapackage/package.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def initialize(descriptor = nil, opts: {})
@opts = opts
@dead_resources = []
self.merge! parse_package(descriptor)
@profile = DataPackage::Profile.new(self.fetch('profile', 'data-package'))
@profile = DataPackage::Profile.new(self.fetch('profile', DataPackage::DEFAULTS[:package][:profile]))
define_properties!
load_resources!
end
Expand Down Expand Up @@ -100,7 +100,6 @@ def update_resources!
load_resource(resource)
rescue ResourceException
@dead_resources << resource['path']
nil
end
end
end
Expand All @@ -113,14 +112,14 @@ def load_resource(resource)
end
end

def default_value(profile_data)
case profile_data['type']
when 'string'
nil
def default_value(field_data)
case field_data['type']
when 'array'
[]
when 'object'
{}
else
nil
end
end

Expand Down
71 changes: 62 additions & 9 deletions lib/datapackage/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,77 @@ module DataPackage
class Resource < Hash
include DataPackage::Helpers

attr_reader :data
attr_reader :name, :profile, :source, :source_type, :valid, :errors

def initialize(resource, base_path = '')
resource = dereference_descriptor(resource, base_path: base_path,
self.merge! dereference_descriptor(resource, base_path: base_path,
reference_fields: ['schema', 'dialect'])
if resource.fetch('data', nil)
@data = resource['data']
elsif resource.fetch('path', nil)
@data = open(join_paths(base_path, resource['path'])).read
apply_defaults!
@profile = DataPackage::Profile.new(self['profile'])
@name = self['name']
get_source!(base_path)
apply_table_defaults! if self.tabular?
end

def table
@table ||= TableSchema::Table.new(self.source, self['schema']) if tabular?
end

def tabular?
tabular_profile = DataPackage::DEFAULTS[:resource][:tabular_profile]
return true if @profile.name == tabular_profile
return true if DataPackage::Profile.new(tabular_profile).valid?(self)
false
end

alias :tabular :tabular?

def valid?
validate
@valid
end

def validate
@errors = @profile.validate(self)
@valid = @profile.valid?(self)
end

private

def get_source!(base_path)
if self.fetch('data', nil)
@source = self['data']
@source_type = 'inline'
elsif self.fetch('path', nil)
unless is_safe_path?(self['path'])
raise ResourceException.new "Path `#{self['path']}` is not safe"
end
@source = join_paths(base_path, self['path'])
@source_type = is_fully_qualified_url?(@source) ? 'remote' : 'local'
else
raise ResourceException.new 'A resource descriptor must have a `path` or `data` property.'
end
self.merge! resource
end

def table
@table ||= TableSchema::Table.new(CSV.parse(data), self['schema']) if self['schema']
def apply_defaults!
self['profile'] ||= DataPackage::DEFAULTS[:resource][:profile]
self['encoding'] ||= DataPackage::DEFAULTS[:resource][:encoding]
end

def apply_table_defaults!
if self.fetch('schema', nil)
self['schema']['missingValues'] = DataPackage::DEFAULTS[:schema][:missing_values]
self['schema'].fetch('fields', []).each do |field_descriptor|
field_descriptor['type'] ||= DataPackage::DEFAULTS[:schema][:type]
field_descriptor['format'] ||= DataPackage::DEFAULTS[:schema][:format]
end
end

if self.fetch('dialect', nil)
DataPackage::DEFAULTS[:dialect].each do |key, val|
self['dialect'][key.to_s] ||= val
end
end
end
end
end
Loading

0 comments on commit 9c2d8c6

Please sign in to comment.