Module: Bxtjson
- Defined in:
- lib/bxtjson.rb
Overview
dependencies
-
gem: json_schema
-
gem: multi_json
-
JSON standard library or other (e.g. oj) json parsers
-
You implement a model in Sequel or ActiveRecord if you want.
Constants (examples)
cleaner_proc = ->(str) {str.gsub(/\W+/, " ").lstrip
.gsub(" ", "_")
.gsub(/PPPO_|PPCO_/, "")
.downcase
}
json_filename = "../../../fsms-tmp/PP_PROPOSAL_2015.JSON"
schema_filename = "./docs/schema.json"
'#/departments/primary_dept'
Class Method Summary collapse
-
.compact_hash!(hash) ⇒ Hash
Recursively remove falsey values from hash Falsey values are those that return true from respond_to(:empty?) or :nil?.
- .compact_values!(hash) ⇒ Object
-
.muscle(json_filename:, schema_filename:, clean_proc: ->(str){str}, model: nil, schema_entity: nil, authorizing_pointer:, data_attr: :data) ⇒ Object
Parse json-schema file and map contents of json file into initialized schema.
-
.skeleton(schema_data:, entity: nil) ⇒ Hash
Initialize an empty hashmap given a json-schema.
-
.text_to_lazy_json(json_filename:, clean_proc:) ⇒ Hash
process a file of jsonl (linefeed) and clean keys with proc.
Class Method Details
.compact_hash!(hash) ⇒ Hash
Recursively remove falsey values from hash Falsey values are those that return true from respond_to(:empty?) or :nil?
108 109 110 111 112 113 114 |
# File 'lib/bxtjson.rb', line 108 def self.compact_hash!(hash) p = proc do |_, v| v.delete_if(&p) if v.respond_to? :delete_if v.respond_to?(:empty?) && v.empty? || v.nil? end hash.delete_if(&p) end |
.compact_values!(hash) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/bxtjson.rb', line 115 def self.compact_values!(hash) Hash[hash.map do |key, value| [key, if value.is_a?(Array) value.map {|item| Bxtjson.compact_hash!(item) } elsif value.respond_to?( :delete_if) Bxtjson.compact_hash!(value) else value end ] end ] end |
.muscle(json_filename:, schema_filename:, clean_proc: ->(str){str}, model: nil, schema_entity: nil, authorizing_pointer:, data_attr: :data) ⇒ Object
Parse json-schema file and map contents of json file into initialized schema
Mapping of contents will search for the first key in the source, that match the schema (recursively). So, the source should be flat for clarity, and the schema can be nested.
If it cannot find a key, it will look for “top/next/final” path key in the source data.
For example, in the skeleton
{key: {nest: "this"} }
Will be filled with “muscle” if the source has a ket
{"key/nest": "data muscle"}
TODO: design interface from csv to json that fits these principles.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/bxtjson.rb', line 75 def self.muscle(json_filename:, schema_filename:, clean_proc: ->(str){str}, model: nil, schema_entity: nil, authorizing_pointer:, data_attr: :data) skeleton = Bxtjson.skeleton(schema_data: MultiJson.load(File.read(schema_filename)), entity: schema_entity) if model model = constantize(model.to_s.capitalize) text_to_lazy_json(json_filename: json_filename, clean_proc: clean_proc ) .map {|data| data = fillin(source_hash: _map_onto_skeleton_of_schema( data, skeleton: skeleton ), skeleton: skeleton) result = model.create( data_attr => data) } else out = [] text_to_lazy_json(json_filename: json_filename, clean_proc: clean_proc ) .map {|data| out << fillin(source_hash: _map_onto_skeleton_of_schema( data, skeleton: skeleton ), skeleton: skeleton) } end end |
.skeleton(schema_data:, entity: nil) ⇒ Hash
Initialize an empty hashmap given a json-schema
28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/bxtjson.rb', line 28 def self.skeleton(schema_data:, entity: nil) schema = JsonSchema.parse!(schema_data) schema. if entity.nil? entity_schema = schema else entity_schema = schema.properties[entity] end return _skeleton(entity_schema, acc: {}) end |
.text_to_lazy_json(json_filename:, clean_proc:) ⇒ Hash
process a file of jsonl (linefeed) and clean keys with proc
44 45 46 47 48 49 50 51 |
# File 'lib/bxtjson.rb', line 44 def self.text_to_lazy_json(json_filename:, clean_proc:) File.foreach(json_filename) .lazy .map do |line| _key_cleaner(data: MultiJson.load(line), clean_proc: clean_proc) end end |