how to save a blob file using carrierwave in rails - ruby-on-rails

So i have a requirement where i record a video and save it in the database, the recording of the video is working fine, only thing is it generates a blob file, then i use js to send the blob file to the server. This are my params
{"testqwe"=>{"attr"=>"blob:http://localhost:3000/6f12f123-b1d0-7bfc-6b15-d3b54341946"}, "controller"=>"myControler", "action"=>"test"}
i have an uploader in place , but it does not save anything.
so how can i save this using carierwave to my database?
here is my javascript
mediaRecorder.onstop = (ev) ->
blob = new Blob(chunks, 'type': 'video/mp4;')
chunks = []
videoURL = window.URL.createObjectURL(blob)
vidSave.src = videoURL
$.ajax
type: 'POST'
content_type: "video/webm"
url: '/test'
enctype: "multipart/form-data"
data: testqwe: attr: videoURL
return

any one still trying to figure out this, u can refer this link
How to pass blob url to rails create method by ajax
mediaRecorder.onstop = (ev) ->
blob = new Blob(chunks, 'type': 'video/mp4;')
chunks = []
videoURL = window.URL.createObjectURL(blob)
vidSave.src = videoURL
formData = new FormData
formData.append('testqwe[attr]', blob);
$.ajax
type: 'POST'
url: '/test'
processData: false
contentType: false
data: formData
return
Send and save the audio/video data as a file

Related

Sencha ExtJS 7 - How to handle Blob, File, FormData instance object

How can i send to server a Blob, File and FormData Instance Object using these two way Ext.Ajax.request and Ext.form.Panel.submit?
var blob = new Blob(chunks, {type: chunks[0].type});
var file = new File(["lorem.."], "test.txt", {type: "text/plain"});
var formData = new FormData();
formData.append("text", file);
formData.append("video", blob, "video.webm");
How to add "formData" or simple "blob" and/or "file" into Ext.Ajax.request(options) and Ext.form.Panel.submit(options)?
Another doubt: How to set "file" into value of "filefield" component?
Thanks!
Something in the line of this might work:
Ext.Ajax.request({url: 'https://some.url.com', method: 'POST', rawData: formData, contentType: false})
You can check out this thread as well.

How to upload an image with nativescript-camera and nativescript-background-http on IOS

I am able to upload a file on android to a C# web api, using nativescript-camera with nativescript-background-http.
I set the params as follows:
var params = [{ name: "image", filename: fileUri, mimeType: 'application/octet-stream' }];
...
And send the request:
let request = {
url: this.API_URL + "/UploadOctetFile",
method: "POST",
headers: {
"Authorization": accessTokenJson,
"Content-Type": "application/octet-stream",
"File-Name": imageName
},
description: "{ 'uploading': " + imageName + " }"
};
return this.session.multipartUpload(params, request);
In android the fileUri is returned in a fairly straight forward manner:
takePictrue.then((imageAsset: ImageAsset) => {
Then imageAsset.android has the file uri that is needed to send the image. However, for ios, imageAsset.ios is a PHAsset. To get the file URI, I use the following code:
let manager = PHImageManager.defaultManager()
let options = new PHImageRequestOptions();
options.resizeMode = PHImageRequestOptionsResizeMode.Exact;
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
manager.requestImageForAssetTargetSizeContentModeOptionsResultHandler(imageAsset.ios, { width: 2048, height: 1536 }, PHImageContentModeAspectFill, options, function (result, info) {
let srcfilePath = info.objectForKey("PHImageFileURLKey").toString();
...
});
In the above: srcfilePath (which I pass as fileUri) is: file:///var/mobile/Media/DCIM/101APPLE/IMG_1902.JPG
The image name is then IMG_1902.JPG
However, this uploads an empty file. I'm guessing that I need to change the fileUri or perhaps I should be using a different method to: requestImageForAssetTargetSizeContentModeOptionsResultHandler.
I have tried the solution suggested here to do:
let fileUri = image.fileUri.replace("file://","");
and I've tried changing the mime type "mimeType":"image/jpg".
Any ideas are much appreciated.
Sam, this might help. I did the following to handle an iOS user selecting a photo from their gallery for use later in the app (Android is simple and straightforward like in your case, but iOS returns a PHAsset):
import { ImageSource } from "image-source";
import { Image } from "tns-core-modules/ui/image";
import { path, knownFolders } from "tns-core-modules/file-system";
//iOS user picks photo...
const iosImg = new ImageSource();
iosImg.fromAsset(myPHAsset).then(imsr => {
this.counter += 1; //class property to allow unique filenames
const folder = knownFolders.documents();
const path2 = path.join(folder.path, `Image${this.counter}.jpg`);
const saved = imsr.saveToFile(path2, "jpg");
const img = new Image();
img.src = path2;
this.data.changeImage(img); //Ng service to allow use of image in other components
});
Links: {N} docs
{N} imagepicker #197
{N} imageUpload code

How to get a file using fetch in 'Code by Zapier'

I was requesting an API that delivers pdf. This also need authorization.
var fileUlr = 'https://api.safetyculture.io/audits/1234/exports/5678.pdf';
var getFile = fetch( fileUlr, { method: 'GET', headers: { 'Authorization': 'Bearer 2034weoiroew' } } )
.then( function( fileBinary ) {
return fileBinary;
});
I am getting the file in binary format. How to convert this to original pdf? Then I need to programmatically upload the file to dropbox/google drive. Can you help me?

How to save base64 image in Blob with Carrierwave in Rails4?

Like described in this Tutorial, I'm converting a canvas into a DataUrl and this DataUrl into a Blob. Then I make an ajax post request and would like to save the image in the Database using Carrierwave.
This is my JS code:
uploadButton.on('click', function(e) {
var dataURL = mycanvas.toDataURL("image/png;base64;");
// Get our file
var file= dataURLtoBlob(dataURL);
// Create new form data
var fd = new FormData();
// Append our Canvas image file to the form data
fd.append("image", file);
// And send it
$.ajax({
url: "/steps",
type: "POST",
data: fd,
processData: false,
contentType: false,
});
});
// Convert dataURL to Blob object
function dataURLtoBlob(dataURL) {
// Decode the dataURL
var binary = atob(dataURL.split(',')[1]);
// Create 8-bit unsigned array
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
// Return our Blob object
return new Blob([new Uint8Array(array)], {type: 'image/png'});
}
When I add the following code to my controller, then the Image get's saved but of course not through carrierwave.
File.open("#{Rails.root}/public/uploads/somefilename.png", 'wb') do |f|
f.write(params[:image].read)
end
Updated Info:
These are the params for my ajax post request:
Parameters: {"image"=>#<ActionDispatch::Http::UploadedFile:0x007feac3e9a8a8 #tempfile=#<Tempfile:/var/folders/0k/q3kc7bpx3_51kc_5d2r1gqcc0000gn/T/RackMultipart20140211-1346-gj7kb7>, #original_filename="blob", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"image\"; filename=\"blob\"\r\nContent-Type: image/png\r\n">}
And these are the params for a standard file upload:
Parameters: {"utf8"=>"✓", "image"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007feac20c2e20 #tempfile=#<Tempfile:/var/folders/0k/q3kc7bpx3_51kc_5d2r1gqcc0000gn/T/RackMultipart20140211-1346-1ui8wq1>, #original_filename="burger.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"image[image]\"; filename=\"xy.jpg\"\r\nContent-Type: image/jpeg\r\n">}}
If I do Image.create(params[:image]) I have transaction rollback...
Error for transaction rollback:
Unprocessable Entity
ActiveRecord::RecordInvalid (Validation failed: image You are not allowed to upload "" files, allowed types: jpg, jpeg, gif, png)
I just wanted to add, you can add the file type in your view while appending your blob.
// Get our file
var file = dataURLtoBlob(dataURL);
// Create new form data
var fd = new FormData();
// Append our Canvas image file to the form data
fd.append("image", file, "blob.jpg");
Note the ending when we define the filename.
Hope this helps someone.
Source: https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
You are whitelisting the filetypes permitted. By default, Carrierwave will attempt to determine the filetype by the filename extension - which isn't being passed since this is actually a Blob object. As such, you're getting a validation error about the file's 'type'. To fix this, simply append the expected filename extension for blob objects:
if params[:image].try(:original_filename) == 'blob'
params[:image].original_filename << '.png'
end
Image.create!(image: params[:image])

ember file upload to rails, encoding and decoding with base64

I'm almost there, but I'm having an issue with decoding of the file. When decoding the file is not correct.
The code that I use to upload the file:
createDataSet: function() {
var data = new FormData();
data.append('original_filename', this.get('fileName'));
data.append('datafile', this.get('newData'));
data.append('project_id', this.get('content.id'));
data.append('name', this.get('content.name'));
$.ajax({
url: '/data_sets.json',
data: data,
cache: false,
contentType: false,
processData: false,
dataType: 'json',
type: 'POST',
success: function(data) {
alert('ok');
},
error: function(xhr, data, errorThrown) {
alert('error');
}
});
}
On the Rails side I'm trying to pick this up with the following method:
def create
# take care of the attachement
datasetfilename = Pathname.new(params[:original_filename]).basename
newfile = File.open(datasetfilename, 'w') do |f|
f.write(Base64.decode64(params[:datafile]))
end
#dataset = DataSet.new
#active_data_set = #dataset.active_data_sets.build
#active_data_set.project_id = params[:project_id]
#active_data_set.save
#dataset.name = params[:name]
#dataset.filename = datasetfilename
#dataset.tempfilename = #dataset.savefile newfile
#dataset.save
end
If I use File.open(datasetfilename, 'w') I get an error like this one Encoding::UndefinedConversionError - "\xAB" from ASCII-8BIT to UTF-8. On the other hand, if I open with 'wb' the resulting file is mingled and can't be read.
I already added the meta tag for the file encoding <meta charset="utf-8" /> but without any difference.
If anybody has any hint that would be appreciated.
Just got this working in one of my own controllers, there are 2 main issues:
1) to resolve the encoding issue, use "w:binary" as the write flag instead of "w" (defaults to ASCII)
2) the :datafile params includes some header info "data:text/csv;base64,SUR4CUluZ...", I'm currently splitting on "," but might be better served to decode everything beyond "base64," as I'm not sure if additional commas are allowed.
My working code (slightly different parameter names):
if params.key?(:img_file)
header, data = params[:img_file].split(',')
img_type = header.match(/image\/([a-z]{1,11});/)[1]
file_path = "imgtodo/fund_#{#fund.id}.#{img_type}"
File.open(Rails.root.join('public',file_path).to_s, 'w:binary') do |f|
f.write(Base64.decode64(data))
end
end

Resources