utils.rb 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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.recursively_symbolize_keys(object)
  22. case object
  23. when Hash
  24. object.inject({}) {|memo, (k, v)| memo[String === k ? k.to_sym : k] = recursively_symbolize_keys(v); memo }
  25. when Array
  26. object.map { |item| recursively_symbolize_keys item }
  27. else
  28. object
  29. end
  30. end
  31. def self.interpolate_jsonpaths(value, data)
  32. value.gsub(/<[^>]+>/).each { |jsonpath|
  33. Utils.values_at(data, jsonpath[1..-2]).first.to_s
  34. }
  35. end
  36. def self.recursively_interpolate_jsonpaths(struct, data)
  37. case struct
  38. when Hash
  39. struct.inject({}) {|memo, (key, value)| memo[key] = recursively_interpolate_jsonpaths(value, data); memo }
  40. when Array
  41. struct.map {|elem| recursively_interpolate_jsonpaths(elem, data) }
  42. when String
  43. interpolate_jsonpaths(struct, data)
  44. else
  45. struct
  46. end
  47. end
  48. def self.value_at(data, path)
  49. values_at(data, path).first
  50. end
  51. def self.values_at(data, path)
  52. if path =~ /\Aescape /
  53. path.gsub!(/\Aescape /, '')
  54. escape = true
  55. else
  56. escape = false
  57. end
  58. result = JsonPath.new(path, :allow_eval => false).on(data.is_a?(String) ? data : data.to_json)
  59. if escape
  60. result.map {|r| CGI::escape r }
  61. else
  62. result
  63. end
  64. end
  65. # Output JSON that is ready for inclusion into HTML. If you simply use to_json on an object, the
  66. # presence of </script> in the valid JSON can break the page and allow XSS attacks.
  67. # Optionally, pass `:skip_safe => true` to not call html_safe on the output.
  68. def self.jsonify(thing, options = {})
  69. json = thing.to_json.gsub('</', '<\/')
  70. if !options[:skip_safe]
  71. json.html_safe
  72. else
  73. json
  74. end
  75. end
  76. def self.pretty_jsonify(thing)
  77. JSON.pretty_generate(thing).gsub('</', '<\/')
  78. end
  79. end