Module: KineticSdk::Utils::KineticExportUtils
Overview
The KineticExportUtils module provides methods to simplify exporting objects and writing to the local file system.
Instance Method Summary collapse
-
#get_variable_property(export_shape, object_path) ⇒ String
Fetches the variable property of a given path (ie slug, name, etc).
-
#prepare_shape(*args) ⇒ Hash
Builds the tree structure of the export including the arguments.
-
#process_export(core_path, export_shape, object, object_path = '', executor: nil) ⇒ Object
Processes and writes data exported from the core service.
- #process_export_old(core_path, export_shape, object, object_path = '', executor: nil) ⇒ Object
-
#should_extract(export_path, export_shape) ⇒ Boolean
Determines if the current path should be extracted further.
- #should_parallelize?(object_path) ⇒ Boolean
-
#write_object_to_file(filename, file_contents) ⇒ Object
Creates directory structure and writes file.
- #write_object_to_file_threaded(filename, file_contents, mutex = nil) ⇒ Object
Instance Method Details
#get_variable_property(export_shape, object_path) ⇒ String
Fetches the variable property of a given path (ie slug, name, etc)
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/kinetic_sdk/utils/kinetic-export-utils.rb', line 67 def get_variable_property(export_shape, object_path) # Prepare the metadata object_path_segments = object_path.split('.') pointer = export_shape # Walk the object path object_path_segments.each do |object_path_segment| # If the object path corresponds to a "variable" if pointer.has_key?(:variable) pointer = pointer[pointer[:variable]] # If the object path corresponds to a static property else pointer = pointer[object_path_segment] end # If the pointer is null (indicating that the property should not be extracted) break if pointer.nil? end # Return the result pointer.nil? ? nil : pointer[:variable] end |
#prepare_shape(*args) ⇒ Hash
Builds the tree structure of the export including the arguments
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/kinetic_sdk/utils/kinetic-export-utils.rb', line 13 def prepare_shape(*args) shape = {} args.each do |arg| segments = arg.split('.') pointer = shape segments.each do |segment| if segment =~ /\{(.*)\}/ pointer[:variable] ||= $1 pointer[$1] ||= {} pointer = pointer[$1] else pointer[segment] ||= {} pointer = pointer[segment] end end end shape end |
#process_export(core_path, export_shape, object, object_path = '', executor: nil) ⇒ Object
Processes and writes data exported from the core service
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/kinetic_sdk/utils/kinetic-export-utils.rb', line 120 def process_export(core_path, export_shape, object, object_path='', executor: nil) # Prepare metadata (same as before) child_objects = {} file_contents = {} if object.kind_of?(Array) file_contents = object else object.each do |key, value| child_object_path = object_path.empty? ? key : "#{object_path}.#{key}" if should_extract(child_object_path, export_shape) if value.kind_of?(Array) variable = get_variable_property(export_shape, child_object_path) if variable.nil? child_objects[child_object_path] = value else value.each do |item| child_objects["#{child_object_path}.#{item[variable]}"] = item end end else child_objects[child_object_path] = value end else file_contents[key] = value end end end if object_path != '' && !file_contents.empty? filename = "#{core_path}/#{object_path.gsub('/', '').gsub('\\', '').gsub('.', '/').gsub(/::/, '-').gsub(/[^ a-zA-Z0-9_\-\/]/, '')}.json" write_object_to_file(filename, file_contents) end # Thread at key levels: root, kapps, and forms should_thread = executor && child_objects.size > 1 && should_parallelize?(object_path) if should_thread puts " -> Spawning #{child_objects.size} threads for: #{object_path}" futures = child_objects.map do |key, child_object| Concurrent::Future.execute(executor: executor) do puts " [Thread #{Thread.current.object_id}] Starting: #{key}" process_export(core_path, export_shape, child_object, key, executor: executor) puts " [Thread #{Thread.current.object_id}] Finished: #{key}" end end futures.each(&:value) else child_objects.each do |key, child_object| process_export(core_path, export_shape, child_object, key, executor: executor) end end end |
#process_export_old(core_path, export_shape, object, object_path = '', executor: nil) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/kinetic_sdk/utils/kinetic-export-utils.rb', line 196 def process_export_old(core_path, export_shape, object, object_path='', executor: nil) # Prepare metadata child_objects = {} file_contents = {} if object.kind_of?(Array) file_contents = object else # For each of the object properties object.each do |key, value| # Build child object path child_object_path = object_path.empty? ? key : "#{object_path}.#{key}" # If the property should be extracted into its own folder/file if should_extract(child_object_path, export_shape) if value.kind_of?(Array) variable = get_variable_property(export_shape, child_object_path) if variable.nil? child_objects[child_object_path] = value else value.each do |item| child_objects["#{child_object_path}.#{item[variable]}"] = item end end else child_objects[child_object_path] = value end # If the property does not need to be extracted else # Add the property to the file contents file_contents[key] = value end end end # If this is not the "root" object if object_path != '' && !file_contents.empty? # Replace all `/` with `` # Replace all `\` with `` # Replace all `.` with `/` # Replace all `::` with `-` (this ensures nested Teams/Categories maintain a separator) # Replace all non-slug characters with `` filename = "#{core_path}/#{object_path.gsub('/', '').gsub('/\\', '').gsub('.', '/').gsub(/::/, '-').gsub(/[^ a-zA-Z0-9_\-\/]/, '')}.json" # Write the file_contents based upon the write_object_to_file(filename, file_contents) end if executor && child_objects.size > 0 futures = child_objects.map do |key, child_object| Concurrent::Future.execute(executor: executor) do # Recursive calls don't use threading process_export(core_path, export_shape, child_object, key) end end futures.each do |future| future.value # This will re-raise any exceptions that occurred end else child_objects.each do |key, child_object| process_export(core_path, export_shape, child_object, key) end end end |
#should_extract(export_path, export_shape) ⇒ Boolean
Determines if the current path should be extracted further
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/kinetic_sdk/utils/kinetic-export-utils.rb', line 37 def should_extract(export_path, export_shape) # Prepare the metadata export_path_segments = export_path.split('.') pointer = export_shape result = true # Walk the export path export_path_segments.each do |export_path_segment| # If the object path corresponds to a "variable" if pointer.has_key?(:variable) pointer = pointer[pointer[:variable]] # If the object path corresponds to a static property else pointer = pointer[export_path_segment] end # If the pointer is null (indicating that the property should not be extracted) if pointer.nil? # Break out of the loop result = false break end end # Return the result result end |
#should_parallelize?(object_path) ⇒ Boolean
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/kinetic_sdk/utils/kinetic-export-utils.rb', line 175 def should_parallelize?(object_path) # Thread at these specific levels parallelize_patterns = [ /^$/, # Root level /^space\.kapps$/, # All kapps /^space\.kapps\.[^.]+$/, # Within each kapp (forms, webhooks, etc) /^space\.kapps\.[^.]+\.forms$/, # All forms within a kapp /^space\.teams$/, # All teams /^space\.bridges$/, # All bridges /^space\.webApis$/, # All webApis /^space\.webhooks$/, # All webhooks ] matches = parallelize_patterns.any? { |pattern| object_path =~ pattern } # DEBUG puts " Checking parallelize for: '#{object_path}' -> #{matches}" matches end |
#write_object_to_file(filename, file_contents) ⇒ Object
Creates directory structure and writes file
92 93 94 95 96 97 98 |
# File 'lib/kinetic_sdk/utils/kinetic-export-utils.rb', line 92 def write_object_to_file(filename, file_contents) # Create Folder if not exists dir_path = File.dirname(filename) FileUtils.mkdir_p(dir_path, :mode => 0700) # Write File File.open(filename, 'w') { |file| file.write(JSON.pretty_generate(file_contents)) } end |
#write_object_to_file_threaded(filename, file_contents, mutex = nil) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/kinetic_sdk/utils/kinetic-export-utils.rb', line 100 def write_object_to_file_threaded(filename, file_contents, mutex=nil) # Create Folder if not exists dir_path = File.dirname(filename) if mutex mutex.synchronize { FileUtils.mkdir_p(dir_path, :mode => 0700) } else FileUtils.mkdir_p(dir_path, :mode => 0700) end # Write File File.open(filename, 'w') { |file| file.write(JSON.pretty_generate(file_contents)) } end |