utils.rb 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. require 'jsonpath'
  2. require 'cgi'
  3. module Utils
  4. def self.unindent(s)
  5. s = s.gsub(/\t/, ' ').chomp
  6. min = ((s.split("\n").find {|l| l !~ /^\s*$/ })[/^\s+/, 0] || "").length
  7. if min > 0
  8. s.gsub(/^#{" " * min}/, "")
  9. else
  10. s
  11. end
  12. end
  13. def self.pretty_print(struct, indent = true)
  14. output = JSON.pretty_generate(struct)
  15. if indent
  16. output.gsub(/\n/i, "\n ").tap { |a| p a }
  17. else
  18. output
  19. end
  20. end
  21. def self.interpolate_jsonpaths(value, data, options = {})
  22. if options[:leading_dollarsign_is_jsonpath] && value[0] == '$'
  23. Utils.values_at(data, value).first.to_s
  24. else
  25. value.gsub(/<[^>]+>/).each { |jsonpath|
  26. Utils.values_at(data, jsonpath[1..-2]).first.to_s
  27. }
  28. end
  29. end
  30. def self.recursively_interpolate_jsonpaths(struct, data, options = {})
  31. case struct
  32. when Hash
  33. struct.inject({}) {|memo, (key, value)| memo[key] = recursively_interpolate_jsonpaths(value, data, options); memo }
  34. when Array
  35. struct.map {|elem| recursively_interpolate_jsonpaths(elem, data, options) }
  36. when String
  37. interpolate_jsonpaths(struct, data, options)
  38. else
  39. struct
  40. end
  41. end
  42. def self.value_at(data, path)
  43. values_at(data, path).first
  44. end
  45. def self.values_at(data, path)
  46. if path =~ /\Aescape /
  47. path.gsub!(/\Aescape /, '')
  48. escape = true
  49. else
  50. escape = false
  51. end
  52. result = JsonPath.new(path, :allow_eval => ENV['ALLOW_JSONPATH_EVAL'] == "true").on(data.is_a?(String) ? data : data.to_json)
  53. if escape
  54. result.map {|r| CGI::escape r }
  55. else
  56. result
  57. end
  58. end
  59. # Output JSON that is ready for inclusion into HTML. If you simply use to_json on an object, the
  60. # presence of </script> in the valid JSON can break the page and allow XSS attacks.
  61. # Optionally, pass `:skip_safe => true` to not call html_safe on the output.
  62. def self.jsonify(thing, options = {})
  63. json = thing.to_json.gsub('</', '<\/')
  64. if !options[:skip_safe]
  65. json.html_safe
  66. else
  67. json
  68. end
  69. end
  70. def self.pretty_jsonify(thing)
  71. JSON.pretty_generate(thing).gsub('</', '<\/')
  72. end
  73. end