Track progress of file upload to google cloud storage via js? - javascript

I'm wondering if it is possible to track the progress of a file upload to google cloud storage when using the javascript client? As I have a progress bar that I would like to show to the user on how much of the file has been uploaded so far.
I'm using the same upload code that google gives on their example page for file upload.

Instead of using the gapi.client.request api provided by the js library I instead created an XMLHttpRequest and appended a event listener for the event progress. As seen by the following:
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
var contentType = fileData.type || 'application/octet-stream';
var metadata = {
'name': 'testing',
'mimeType': contentType
};
var base64Data = btoa(reader.result);
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n' +
'\r\n' +
base64Data +
close_delim;
gapi.client.request()
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://www.googleapis.com/upload/storage/v1/b/bucket/o?uploadType=multipart&key=apiKey&alt=json', true);
xhr.setRequestHeader('Content-Type', 'multipart/mixed; boundary="' + boundary + '"');
xhr.setRequestHeader('authorization', 'Bearer ' + gapi.auth.getToken().access_token);
xhr.upload.addEventListener("progress", function(e) {
var pc = parseFloat(e.loaded / e.total * 100).toFixed(2);
}, false);
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
console.log(xhr.responseText);
}
};
xhr.send(multipartRequestBody);
Attribution: Majority of code was taken from Google's js library with the only addition being the event listener for listening to the progress of the upload.

Related

Issue while uploading file in google drive with multi part settings using javascript rest apis (v2 and V3)

I want to upload a file to google drive with metadata, I am using the rest APIs and providing all the required details. The request is successfully completed, and files are created with the metadata, but the file size is just 13 byte.
here is the code
function addFileToFolder(arrayBuffer, i) {
var index = i;
var fileName = files[index].name;
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var fileContnet="this is the simple text file"
const contentType = 'application/json';
const contentTypeImage = 'application/octet-stream';
var metadata = {
'name': fileName,
'mimeType': contentTypeImage
};
var multipartRequestBody =
delimiter +
'Content-Type:application/json \r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentTypeImage + '\r\n\r\n' +
files[index] +
close_delim;
// var fileCollectionEndpoint ="https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart";
var len=(arrayBuffer.byteLength);
alert(len);
var request = gapi.client.request({
'path': '/upload/drive/v3/files',
'method': 'POST',
'params': {'uploadType': 'multipart'},
'headers': {
'Content-Type': 'multipart/related; boundary="' + boundary + '"',
'Content-Length':len
},
'body': multipartRequestBody});
request.execute(function(data){console.log(data)});
//----------------------
}
}
I tried various solutions.
I changed the arrayBuffer to files[i]
for Content-length I added (arrayBuffer.bytelength+metadata.lenght)
and (file[0].size+metadata.length)
but no luck
I tried a simple upload with no metadata, it works and a file is uploaded with untitled name.
is there any one who faces the same issue and can sugggest me the solution

Unable to upload macro enabled files such as .docm/.pptm/.xlsm

I was trying to write simple javascript code to convert and upload files to Google Drive using Drive REST api(So that only converted document to google document format will be uploaded). I got succided in uploading docx/xlsx/pptx documents however when I am trying to macro enabled files such as .docm/.pptm/.xlsm I am getting error "Bad Request" shown in screenshot:Error while uploading .docm file
My JavaScript code looks like:
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<input type="file" id="fileToUpload"></input>
<button onclick="insertFile()">Pick File to Upload</button>
<script type="text/javascript">
var CLIENT_ID = 'CLIENT_ID_HERE';
var SCOPES = 'https://www.googleapis.com/auth/drive';
var FOLDER_ID = '';
/**
* Called when the client library is loaded to start the auth flow.
*/
function handleClientLoad() {
window.setTimeout(checkAuth, 1);
}
/**
* Check if the current user has authorized the application.
*/
function checkAuth() {
gapi.auth.authorize(
{'client_id': CLIENT_ID, 'scope': SCOPES},
handleAuthResult);
}
/**
* Called when authorization server replies.
*
* #param {Object} authResult Authorization result.
*/
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
console.log("Auth OK !!!");
}
}
function insertFile() {
fileData = document.getElementById("fileToUpload").files[0];
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
var contentType = fileData.type || 'application/octet-stream';
var metadata = {
'title': fileData.fileName,
'mimeType': contentType
};
var base64Data = btoa(reader.result);
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n' +
'\r\n' +
base64Data +
close_delim;
var request = gapi.client.request({
'path': '/upload/drive/v2/files',
'method': 'POST',
'params': {'convert': true},
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
},
'body': multipartRequestBody});
request.execute((file) => {
console.log(file);
});
}
}
</script>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
EDIT:
Earlier I thought 'Google Drive does not support converting macro enabled files'. However when I tried to convert and upload the macro enabled files using python script I was able to do that . Python code:
http = httplib2.Http()
credentials.authorize(http)
drive_service = apiclient.discovery.build('drive', 'v2', http=http)
metadata = {'title': 'test_file.docm',
'mimeType' : 'application/vnd.ms-word.document.macroEnabled.12',}
res = drive_service.files().insert(convert='True',body=metadata,
media_body='test_file.docm', fields='mimeType,exportLinks').execute()
Am I missing anything in Javascript code?

Dynamically Add Content in Google Drive Document File

I have create dynamical file and after I have to add some dynamic content from fckeditor put on that file on save button how to add content or text. Add on google document file using java script code of google drive API in PHP.
function gd_updateFile()
{
var my_text = "your content";
var folderId = "fileid";
var fileId = "your folder id ";
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var contentType = "text/html";
var metadata = {'mimeType': contentType,};
var multipartRequestBody =
delimiter + 'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter + 'Content-Type: ' + contentType + '\r\n' + '\r\n' +
my_text +
close_delim;
var request = gapi.client.request({
'path': '/upload/drive/v2/files/'+folderId+"?fileId="+fileId+"&uploadType=multipart",
'method': 'PUT',
'params': {'fileId': fileId, 'uploadType': 'multipart'},
'headers': {'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'},
'body': multipartRequestBody,
callback:callback,
});
$(".update_file_out_put").html(callback);
if (!callback)
{
callback = function(file)
{
//console.log(file);
};
}
}

Google Document Update API Javascript

I want to update my google document from my website by text area ( auto save on google docs )
How can I use this? Do I need google access key and where to use the key ?
<script type="text/javascript">
function updateFile(fileId, fileMetadata, fileData, callback) {
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
var contentType = fileData.type || 'application/octet-stream';
// Updating the metadata is optional and you can instead use the value from drive.files.get.
var base64Data = btoa(reader.result);
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(fileMetadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n' +
'\r\n' +
base64Data +
close_delim;
var request = gapi.client.request({
'path': '/upload/drive/v2/files/' + fileId,
'method': 'PUT',
'params': {'uploadType': 'multipart', 'alt': 'json'},
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
},
'body': multipartRequestBody});
if (!callback) {
callback = function(file) {
console.log(file)
};
}
request.execute(callback);
}
}
</script>

updating the content of a file stored on Google Drive

I'm trying to use javascript in order to set the contents of a file stored on Google Drive (for example, a .txt or .java file) to a specific String.
I know that the proper way to update a file stored on Google Drive is
function updateFile(fileId, fileMetadata, fileData, callback) {
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
//console.log("fileId: "+fileId+" fileData: "+fileData);
var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
console.log("reader initialized");
var contentType = fileData.type || 'application/octet-stream';
// Updating the metadata is optional and you can instead use the value from drive.files.get.
var base64Data = btoa(reader.result);
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(fileMetadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n' +
'\r\n' +
base64Data +
close_delim;
var request = gapi.client.request({
'path': '/upload/drive/v2/files/' + fileId,
'method': 'PUT',
'params': {'uploadType': 'multipart', 'alt': 'json'},
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
},
'body': multipartRequestBody});
if (!callback) {
callback = function(file) {
console.log(file)
};
}
request.execute(callback);
}
}
but this has not worked in setting the content to a specific String.
Never mind. I found the answer to my problem. Using the method updateFile from my question:
function save(fileId, content){
var contentArray = new Array(content.length);
for (var i = 0; i < contentArray.length; i++) {
contentArray[i] = content.charCodeAt(i);
}
var byteArray = new Uint8Array(contentArray);
var blob = new Blob([byteArray], {type: 'text/plain'});
var request = gapi.client.drive.files.get({'fileId': fileId});
request.execute(function(resp) {
updateFile(fileId,resp,blob,changesSaved);
// the callback^^^^^^
});
}

Categories