Invalid base64 string from Ruby controller - ruby-on-rails

All I want to do is respond with a base64 string when this action on my controller is contactacted.
class V1::AppProxyController < ApplicationController
def logo
send_file("#{Rails.root}/public/fresh_modal.png",
type: "image/png",
disposition: "inline")
end
But the response, when I put it into an online converter, does not return the image. Plus it has all those odd characters. What am I doing wrong?
"�PNG
IHDRZ
�*tEXtSoftwareAdobe ImageReadyq�e< iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c060 61.134777, 2010/02/12-17:32:00 "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop CS5 Windows" xmpMM:InstanceID="xmp.iid:56A07D6E335911E7B92CC44F92F10C15" xmpMM:DocumentID="xmp.did:56A07D6F335911E7B92CC44F92F10C15"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:56A07D6C335911E7B92CC44F92F10C15" stRef:documentID="xmp.did:56A07D6D335911E7B92CC44F92F10C15"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>&���IDATx��Yy�]U��]�6�7K;��L�^���(aS*�����(U�H��A!`E�
Fb�&P ����S�Bי��v��0�[�g���w�yCJĶ�5��{������߹t�i�ȥA��U-�ќ%2$袙��9¥���vl��*Pu��fd�G�C�h�vn����ς�$��K����"q(?��$��˒�ȥ��%8�s^�4���h� r�C[�'|�v�1)#��D������#���x�w�MO��
��C�����Q�H���y�������:�ʣ듮�pF��=��.RZ���?��t��'�Y�%����kZ#���|�&�wOx�B��N���љ�EȓG!��/�j�Q��̄c�q�j���gj�u�Չ��^��Z�%�T�q�S&��v��
i�l;
�A��>��#J�Ԁ��Kr���3^e��Q
�2�u�(�
�H.�ڕ�ۑ�kѿQ�}2��"H�%$�!\n� wC��9�<kmyзX��:.�L��w��}��*���e�O�T[�ӣ�G�кCfֶ'#�����`p%�
5f��Q,���9�#������.Wb�{ E�x;~�dp+��07Ɇ��m�Z��D�b0< :'�&���a��I���Z��zkM ������ wA.��
� �5����:�Bf�ޞ��y�-rVxal*!��+�s����v�|ځ�j��GÖ9ў<�Ga�єt(���bd���c;,�l���u���� � i�A{��Z�N��
M�����[�+>�{�ju�?N��y�Qu�Ċ��kv���Ha �S%!/#�Cx��G�����}Eu�"���!������(�mD��[�T���O��N��;v!�N�-�g"���Ӎ5r�}Wm�
�����.x�-�{-��ހ
���a�?#��.7J���7�~Zs�`jhS�J��ϋ��1��C�k��v�&�No]ek�lA\j��~pEz��)�r��؉����T&.x�>� i����HRG^S�Ly
y: �2h�u8��Upj!j����x���D�(]�q�'6�6���\�����H|v䜊s+�r/dnٺn�Cx��x�����Y�w:R!i-��Z���W�~�vl���[(�ߣR��i�}���h[ "���n���8�;�{�W�]B�R�>�l�\9'��m�Cu�V���G��(=
W=6ӓm���
Қ��z�oH�Q����ꅢ
�!�,r���t��Tq�"�-thQ�F��h+�g�|���[8 �b���ƹ�
��k��z��Z�݌�sh�/��e�1YfD�
hJ���x����J9?���I)>B?]�Ov�TA"��B�|/��$�q�δ�cC�v�Խ��� ��ja�;�Q�㺫�R��\���z?�Xi�H��+)��m���獪��~�mU���wUT�V�2x=RBeh�V�&��KE�F���u��L4��P�fv������3Fw[�]*��N� o���}��hq�,���kVa�F<6�8�A��AQ~�o��FF4���s�&8T1d��X*�(�6^��Ps�w�����#C���0R�z1M"�z�GUQDSD)I?��W)�N�}�a����:1�44}�~��2*��\o5�a�>�7�x�-����8�<� mĻ�޹Ɩ�!���=�FG�����0������N�x��#!�t��C��w��M�;�JQ��2Rt{��e�H�v�q>�H�#Ͳ��FQ�ݾcvH��y���J���>�5c�!�&��x����J0�lҥ9��r�
4���q ��r=��y�����t��p���Ә=�g�*�Z�:���XO�(� ��Qm���nJ���P���{��0���D3-j�C[�|g#��n�#���V����h*����5����i�?d%�u�R��B� ߉����h��fG���,h��,�;��.�U��oJ��I
�����8�!�����������t̒{16��S�0�]���P�i�Ci����H��Fd
=�K��,��+����m��y�w$������[�F�G=?���a8�=�J�ل��0J�\����c��ӡ�zk�G��_-ݟ����5�S+��G���/΃l��)<8��;��=\��M��2�K��V�%���؃��x�\g�|��ay+��B8�QEX,R��G��h�,R_�"Cf�,���j�LFDbic#�v5��
G}rQ��:+]�_���P�b�>�L^*�X����LD��8DE��'Γ&>?
"����0<2gL:��YuL����|��"�
7��~����Ɇ]]vY��Ts7�w8�\x�Dl�Ur<��eU~���)���g��&E7���n�On#�>��q�X+r��ZN��s�κ8DCj
G��HKن+�N�tg�V�Y�)_ڿc�-�r��3��5��B?���1`zvILa�Y���0v������k�=��ډ��(J�&������W#:{�[?�?�]�+[�����H�k�!�<�vf;��x�ڢ��&��-J��ǠÆE�"�+�5�4�^�yl ���b�*��a�Ɠ�B����
i�!�����i�:����b����c��#�j��p$�����:->�}הNǓE)�h9�OB�e��Ü�3��腦��\S5ca�ɘ,�p�C�C��T8���nK���X6L���c?� �r���B-���i>�*�ǁ��͂�����W
_l��ȳ[ૻ��W6Sh���#��I����<��6�H{%2A��g��60��.��A��m0J?t'`�<�a,,m�x>��q�K[Z> Z���'��.��y��5�M�� #ĝ�JₔSe��g����J��VtQ�^
��AyU�O�R[`FV*�U���d�A��K�a�S�����h�Gڑ���Y�?�б.�c)�1��~�_ƙ(S���IEND�B`�"

You need to encode the file to Base64 instead of returning the binary data
File.open("#{Rails.root}/public/fresh_modal.png", 'rb') do |img|
base64_file = 'data:image/png;base64,' + Base64.strict_encode64(img.read)
end
render plain: base64_file

Related

How to parse XML with non-pair tags using Nokogiri

All examples seen on the internet are XML files with structure like:
<open_tag>data that I want</close_tag>
but my XML file is different:
<Report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="_x0034_00_x0020_-_x0020_Nomenklatury" xsi:schemaLocation="_x0034_00_x0020_-_x0020_Nomenklatury http://pcisrs/ReportServer?%2FTARIC%20Reporty%20Ciselnikov%2F400%20-%20Nomenklatury&rs%3AFormat=XML&rc%3ASchema=True" Name="400 - Nomenklatury">
<table1>
<Detail_Collection>
<Detail goods_nomenclature_item_id="0100000000" product_line="80" date_start="31.12.1971" quantity_indents="0" declarable_import="0" declarable_export="0" goods_nomenclature_item_description="ŽIVÉ ZVIERATÁ"/>
<Detail goods_nomenclature_item_id="0101000000" product_line="80" date_start="01.01.1972" quantity_indents="1" statistical_unit="NAR" declarable_import="0" declarable_export="0" goods_nomenclature_item_description="Živé kone, somáre, muly a mulice" parent_goods_nomenclature_item_id="0100000000" parent_product_line="80"/>
.....ETC....
</Detail_Collection>
</table1>
</Report>
If I understand the tutorials, this should work:
subor = Nokogiri::XML(File.open('vendor/financnasprava/nomenklatury/recent.xml'))
dataset = subor.xpath('//Detail')
but didn't.
You can work with this data like in the example below. I removed the source path as I have not this data locally.
If i'm right and you are trying to the access Detail attributes:
require 'nokogiri'
require 'open-uri'
data_xml = <<-EOT
<Report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="400 - Nomenklatury">
<table1>
<Detail_Collection>
<Detail goods_nomenclature_item_id="0100000000" product_line="80" date_start="31.12.1971" quantity_indents="0" declarable_import="0" declarable_export="0" goods_nomenclature_item_description="ŽIVÉ ZVIERATÁ"/>
<Detail goods_nomenclature_item_id="0101000000" product_line="80" date_start="01.01.1972" quantity_indents="1" statistical_unit="NAR" declarable_import="0" declarable_export="0" goods_nomenclature_item_description="Živé kone, somáre, muly a mulice" parent_goods_nomenclature_item_id="0100000000" parent_product_line="80"/>
</Detail_Collection>
</table1>
</Report>
EOT
subor = Nokogiri::XML(data_xml)
dataset = subor.xpath('//Detail_Collection/*')
details = dataset.map do |row|
{
product_line: row.attributes['product_line'].value,
goods_nomenclature_item_id: row.attributes['goods_nomenclature_item_id'].value
}
end
puts details
#=> {:product_line=>"80", :goods_nomenclature_item_id=>"0100000000"}
#=> {:product_line=>"80", :goods_nomenclature_item_id=>"0101000000"}

Ruby on rails save base64 to xlsx (or pdf or word) and save it with paperclip

I have a base64 like this which I have generated on-line.It's for an xlsx file. I want to decode it and save it in db with paperclip so I did this :
decoded_data = Base64.decode64(Base64)
data = StringIO.new(decoded_data)
data.class_eval do
attr_accessor :content_type, :original_filename
end
data.content_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Model.create(file: data)
it creates a file and saves it on database but the file is damaged. I've tried it for image with image content type and it's fine but for pdf,word and xlsx it's not fine . Do you have any clue ?
Thanks in advance.
I've fixed the issue. The problem was for the content type.When I tried to store the files through rails_admin the file_content_type was :
for xlsx file content_type = "application/zip"
for csv file content_type = "text/plain"
for pdf file content_type = "application/pdf"
for word file content_type = "application/zip"
for image file content_type = "image"
But when I was trying to store the base64 file the content_type was quite different as you see below:
for xlsx file content_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
for csv file content_type = "text/plain"
for pdf file content_type = "application/pdf"
for word file content_type = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
for image file content_type = "image/jpg"
So I replaced that correct type and the problem soveld.
decoded_data = Base64.decode64(modified_base64)
data = StringIO.new(decoded_data)
data.class_eval do
attr_accessor :content_type, :original_filename
end
if params[:contentType] == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
#content_type = "application/zip"
elsif params[:contentType] == "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
#content_type = "application/zip"
elsif params[:contentType] == "text/plain"
#content_type = "text/plain"
elsif params[:contentType] == "application/pdf"
#content_type = "application/pdf"
elsif params[:contentType].include?('image')
#content_type = "imgae"
end
data.content_type = #content_type
data.original_filename = params[:file_name]
And don't forget to set the file name, for example if the file is xlsx you can name it as sample.xlsx that's a big deal.

Upload base64 encoded image with paperclip - Rails

Using cropit I get the image bas64 encode on rails through params.
image = params['image'].gsub('data:image/jpeg;base64,', '')
decoded_file = Base64.decode64(image)
and then I save to amazon s3 with paperclip
begin
file = Tempfile.new(['image', '.jpg'])
file.binmode
file.write decoded_file
unless params['image_id']
media_img = Media::Image.new()
media_img.image = file
if media_img.save
render json: {status: 'success'}
else
render json: {status: 'error'}
end
else
img = Media::Image.find(params['image_id'])
img.update_attribute(:image, file)
img.update_attribute(:name, params['image_name'])
render json: {status: 'success'}
end
file.close
ensure
file.unlink
end
The main problem is that the code is working only for jpeg images because I use gsub only for data:image/jpeg;base64, and when creating the Tempfile I created jpg Tempfile.new(['image', '.jpg']) . So how can I handle with best practice jpg, jpeg and png?
This is my solution, using Paperclip.io_adapters.for(image) where image is base64 string.
def create_image image, image_name, cat
signature = Paperclip.io_adapters.for(image)
base_name = File.basename(image_name,File.extname(image_name))
signature.original_filename = "#{base_name}.jpg"
media_img = Media::Image.new()
media_img.image = signature
media_img.company_id = current_company_id
media_img.type = cat
media_img.save
end

Change encoding of a file with grails

In my view i have a upload form:
<input type="file" name="file" value="search file" /><br />
In my controller I load it like that:
def file = request.getFile('file')
def f = file.getInputStream()
def input = f.getText()
So I have now a String called input with the content of the file.
I want it in UTF-8. How is this possible ?
Edit:
My problem is, that the file to be uploaded is in "Windows-1252" and German characters like äöü are different now in the string called "input".
If i convert the file with "Notepad++" in UTF-8 and then upload it, it works. But I cant do that every time.
Edit2:
def file = request.getFile('file') //get file from view
def File tmpfile = new File('C:/tmp/tmpfile.txt') //create temporary file
file.transferTo(tmpfile) //copy into tmpfile
CharsetToolkit toolkit = new CharsetToolkit(tmpfile) //toolkit with tmpfile
def charset = toolkit.getCharset() //save charset in a variable
def input = tmpfile.getText(charset) //get text with right charset
I tried this with a few different documents. But the variable charset is always UTF_8
You can use getText(String charset)
def input = f.getText('UTF-8')
I found a solution:
I used java-bib called jUniversalChardet and wrote the following method:
String getEncoding ( def inputstream ) {
def byte[] buf = new byte[4096]
def UniversalDetector detector = new UniversalDetector(null)
def nread
while ((nread = inputstream.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread)
}
detector.dataEnd();
def encoding = detector.getDetectedCharset()
return encoding
}
In my code i have the following now:
def file = request.getFile('file')
def f = file.getInputStream()
def encoding = getEncoding(file.getInputStream())
def input = f.getText(encoding)
And it works :)

Convert base64 image to StringIO for Carrierwave

I am hoping someone can help me understand this. I have a base64 string for an image:
"data:image/jpeg;base64,/9j/4AAQSkZJRgABA..."
I would like to send it using ember's createRecord and commit():
this.get('store').createRecord(Emb.Painting, {name: newName, image: newImage});
Then I want to convert it to StringIO for carrierwave and save it:
StringIO.class_eval { def original_filename; "stringiohaxx.jpg"; end }
io = StringIO.new(Base64.decode64(params[:painting][:image]))
#painting = Painting.create(:name => params[:painting][:name], :image => io )
An image is saved. The image is always corrupted. Do I need to break my break my base64 string into:
data: '/9j/..'
type: 'image/jpeg'
? Any help appreciated.
Yes, you need to split the string. You could use something like this:
def splitBase64(uri)
if uri.match(%r{^data:(.*?);(.*?),(.*)$})
return {
type: $1, # "image/png"
encoder: $2, # "base64"
data: $3, # data string
extension: $1.split('/')[1] # "png"
}
end
end
Then you can decode the image...
base64image = params[:painting][:image]
imageDataString = splitBase64(base64image)[:data]
imageDataBinary = Base64.decode64(imageDataString)
Then you can pass the imageDataBinary to StringIO.new() and the resulting image should be valid.
And yes that string does need to be broken up:
var data = newImage.split(',');
this.get('store').createRecord(Emb.Painting, {name: newName, image: data[1]});
I doubt this is the best way...

Resources