Module: Brick::Rails
- Defined in:
- lib/brick/frameworks/rails/engine.rb
Defined Under Namespace
Modules: FormBuilder, FormTags Classes: Engine
Class Method Summary collapse
- .display_binary(val, max_size = 100_000) ⇒ Object
- .display_value(col_type, val, lat_lng = nil) ⇒ Object
Class Method Details
.display_binary(val, max_size = 100_000) ⇒ Object
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 103 104 105 106 107 108 109 110 111 |
# File 'lib/brick/frameworks/rails/engine.rb', line 78 def display_binary(val, max_size = 100_000) return unless val @image_signatures ||= { (+"\xFF\xD8\xFF\xEE").force_encoding('ASCII-8BIT') => 'jpeg', (+"\xFF\xD8\xFF\xE0\x00\x10\x4A\x46\x49\x46\x00\x01").force_encoding('ASCII-8BIT') => 'jpeg', (+"\xFF\xD8\xFF\xDB").force_encoding('ASCII-8BIT') => 'jpeg', (+"\xFF\xD8\xFF\xE1").force_encoding('ASCII-8BIT') => 'jpeg', (+"\x89PNG\r\n\x1A\n").force_encoding('ASCII-8BIT') => 'png', '<svg' => 'svg+xml', # %%% Not yet very good detection for SVG (+'BM').force_encoding('ASCII-8BIT') => 'bmp', (+'GIF87a').force_encoding('ASCII-8BIT') => 'gif', (+'GIF89a').force_encoding('ASCII-8BIT') => 'gif' } if val[0..1] == "\x15\x1C" # One of those goofy Microsoft OLE containers? package_header_length = val[2..3].bytes.reverse.inject(0) {|m, b| (m << 8) + b } # This will often be just FF FF FF FF # object_size = val[16..19].bytes.reverse.inject(0) {|m, b| (m << 8) + b } friendly_and_class_names = val[20...package_header_length].split("\0") object_type_name_length = val[package_header_length + 8..package_header_length+11].bytes.reverse.inject(0) {|m, b| (m << 8) + b } friendly_and_class_names << val[package_header_length + 12...package_header_length + 12 + object_type_name_length].strip # friendly_and_class_names will now be something like: ['Bitmap Image', 'Paint.Picture', 'PBrush'] real_object_size = val[package_header_length + 20 + object_type_name_length..package_header_length + 23 + object_type_name_length].bytes.reverse.inject(0) {|m, b| (m << 8) + b } object_start = package_header_length + 24 + object_type_name_length val = val[object_start...object_start + real_object_size] end if ((signature = @image_signatures.find { |k, _v| val[0...k.length] == k }&.last) || (val[0..3] == 'RIFF' && val[8..11] == 'WEBP' && binding.local_variable_set(:signature, 'webp'))) && val.length < max_size "<img src=\"data:image/#{signature.last};base64,#{Base64.encode64(val)}\">" else "< #{signature ? "#{signature} image" : 'Binary'}, #{val.length} bytes >" end end |
.display_value(col_type, val, lat_lng = nil) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/brick/frameworks/rails/engine.rb', line 6 def display_value(col_type, val, lat_lng = nil) is_mssql_geography = nil # Some binary thing that really looks like a Microsoft-encoded WGS84 point? (With the first two bytes, E6 10, indicating an EPSG code of 4326) if col_type == :binary && val && val.length < 31 && (val.length - 6) % 8 == 0 && val[0..5].bytes == [230, 16, 0, 0, 1, 12] col_type = 'geography' is_mssql_geography = true end case col_type when 'geometry', 'geography' if Object.const_defined?('RGeo') @is_mysql = ['Mysql2', 'Trilogy'].include?(ActiveRecord::Base.connection.adapter_name) if @is_mysql.nil? @is_mssql = ActiveRecord::Base.connection.adapter_name == 'SQLServer' if @is_mssql.nil? val_err = nil if @is_mysql || (is_mssql_geography ||= (@is_mssql || (val && val.length < 31 && (val.length - 6) % 8 == 0 && val[0..5].bytes == [230, 16, 0, 0, 1, 12]) ) ) # MySQL's \"Internal Geometry Format\" and MSSQL's Geography are like WKB, but with an initial 4 bytes that indicates the SRID. if (srid = val&.[](0..3)&.unpack('I')) val = val.dup.force_encoding('BINARY')[4..-1].bytes # MSSQL spatial bitwise flags, often 0C for a point: # xxxx xxx1 = HasZValues # xxxx xx1x = HasMValues # xxxx x1xx = IsValid # xxxx 1xxx = IsSinglePoint # xxx1 xxxx = IsSingleLineSegment # xx1x xxxx = IsWholeGlobe # Convert Microsoft's unique geography binary to standard WKB # (MSSQL point usually has two doubles, lng / lat, and can also have Z) if is_mssql_geography if val[0] == 1 && (val[1] & 8 > 0) && # Single point? (val.length - 2) % 8 == 0 && val.length < 27 # And containing up to three 8-byte values? val = [0, 0, 0, 0, 1] + val[2..-1].reverse else val_err = '(Microsoft internal SQL geography type)' end end end end unless val_err || val.nil? val = if ((geometry = RGeo::WKRep::WKBParser.new.parse(val.pack('c*'))).is_a?(RGeo::Cartesian::PointImpl) || geometry.is_a?(RGeo::Geos::CAPIPointImpl)) && !(geometry.y == 0.0 && geometry.x == 0.0) # Create a POINT link to this style of Google maps URL: https://www.google.com/maps/place/38.7071296+-121.2810649/@38.7071296,-121.2810649,12z "<a href=\"https://www.google.com/maps/place/#{geometry.y}+#{geometry.x}/@#{geometry.y},#{geometry.x},12z\" target=\"blank\">#{geometry.to_s}</a>" end end val_err || val else '(Add RGeo gem to parse geometry detail)' end when :binary ::Brick::Rails.display_binary(val) else if col_type if lat_lng && !(lat_lng.first.zero? && lat_lng.last.zero?) # Create a link to this style of Google maps URL: https://www.google.com/maps/place/38.7071296+-121.2810649/@38.7071296,-121.2810649,12z "<a href=\"https://www.google.com/maps/place/#{lat_lng.first}+#{lat_lng.last}/@#{lat_lng.first},#{lat_lng.last},12z\" target=\"blank\">#{val}</a>" elsif val.is_a?(Numeric) && ::ActiveSupport.const_defined?(:NumberHelper) ::ActiveSupport::NumberHelper.number_to_delimited(val, delimiter: ',') else ::Brick::Rails::FormBuilder.hide_bcrypt(val, col_type == :xml) end else '?' end end end |