Can't copy file and convert mime type with Google Drive Api - google-docs-api

I created a new google doc successfully in my drive, but now I wish to change the file type from 'application/msword' to 'application/vnd.google-apps.document'.
I tried to use the answer here to copy the file, but it's not working:
convert a Word doc into a Google doc using the API via nodejs using drive.files.copy convert in v3 of Google Drive API
The code I have is similar to the above question.
After I create the document as msword I am trying to make a simple copy to convert it to a google doc.
drive.files.create({
requestBody: body.requestBody,
fields: 'id',
}, function (err: any, file: any) {
if (err) {
console.error(err);
} else {
drive.files.copy(
{
fileId: file.data.id,
requestBody: { // You can also use "resource" instead of "requestBody".
name: 'copy',
mimeType: "application/vnd.google-apps.document"
}
},
(err, res) => {
if (err) return console.log("The API returned an error: " + err);
console.log(res.data); // If you need, you can see the information of copied file.
}
);
}
the error I'm getting is
Conversion of the uploaded content to the requested output type is not supported.
Any help is appreciated, thanks!

After making some tests with different mime types from Microsoft Office, it looks like the Office editing mode from Google Drive is unable to read blank files and therefore you were getting the error message.
If I am not mistaken, the way Google Drive works to change files formatting is that they need to open the file first in order to read the information and change the formatting. However, in this case Google Drive is recognizing these blank files as corrupted files and is unable to open them using the Office editing mode.
This looks like an expected behavior but could also be considered as a bug from this specific feature. I would recommend you to post your question in the Google Issue Tracker and explain the behavior and testing you have done so far so that you can confirm if this is just expected or a bug from the Office editing mode.
Reference:
Google Drive Office editing mode
Google Issue Tracker

Related

Amplify Video - How to upload a video to the "Input" bucket with swift?

I have an IOS project using Amplify as a backend. I have also incorporated Amplify Video in the hope of supporting video-on-demand. After adding Amplify Video to the project, an "Input" and "Output" bucket is generated. These appear outside of my project environment when visualised via the Amplify Console. They can only be accessed via navigating to AWS S3 console. My questions is, how to I upload my videos via swift to the "Input" bucket via Amplify (or do I not)? The code I have below uploads the video to the S3 bucket within the project environment. There is next to no support for Amplify Video for IOS (Amplify Video Documentation)
if let vidData = self.convertVideoToData(from: srcURL){
let key = "myKey"
//let options = StorageUploadDataRequest.Options.init(accessLevel: .protected)
Amplify.Storage.uploadData(key: key, data: vidData) { (progress) in
print(progress.fractionCompleted)
} resultListener: { (result) in
switch result{
case .success(_ ):
print("upload success!")
case .failure(let error):
print(error.errorDescription)
}
}
}
I'm facing the same issue.. As far as I can tell the iOS Amplify library's amplifyconfiguration.json is limited to using one storage spec under S3TransferUtility.
I'm in the process of solving this issue myself, but the quick solution is to modify the created AWS video resources to run off the same bucket (input and output). Now, be warned I'm an iOS Engineer, not backend, only getting familiar with AWS.
Solution as follows:
The input bucket the amplify video plugin created has 4 event notifications under the properties tab. These each kick off a VOD-inputWatcher lambda function. Copy these 4 notifications to your original bucket
The output bucket has two event notifications, copy those also to the original bucket
Try the process now, drop a video into your bucket manually. It will fail but we'll see progress - the MediaConvert job is kicked off, but will tell you it failed because it didn't have permissions to read the files in your bucket. Something like Unable to open input file, Access Denied. Let's solved this:
Go to the input lambda function and add this function:
async function enableACL(eventObject) {
console.log(eventObject);
const objectKey = eventObject.object.key;
const bucketName = eventObject.bucket.name;
const params = {
Bucket: bucketName,
Key: objectKey,
ACL: 'public-read',
};
console.log(`params: ${eventObject}`);
s3.putObjectAcl(params, (err, data) => {
if (err) {
console.log("failed to set ACL");
console.log(err);
} else {
console.log("successfully set acl");
console.log(data);
}
});
}
Now call it from the event handler, and don't forget to add const s3 = new AWS.S3({}); on top of the file:
exports.handler = async (event) => {
// Set the region
AWS.config.update({ region: event.awsRegion });
console.log(event);
if (event.Records[0].eventName.includes('ObjectCreated')) {
await enableACL(event.Records[0].s3);
await createJob(event.Records[0].s3);
const response = {
statusCode: 200,
body: JSON.stringify(`Transcoding your file: ${event.Records[0].s3.object.key}`),
};
return response;
}
};
Try the process again. The lambda will fail, you can see it in the lambda's CloutWatch: failed to set ACL. INFO AccessDenied: Access Denied at Request.extractError. To fix this we need to give S3 permissions to the input lambda function.
Do that by navigating to the lambda function's Configuration / Permissions and find the Role. Open it in IAM and add Full S3 access. Not ideal, but again, I'm just trying to make this work. Probably would be better to specify the exact Bucket and correct actions only. Any help regarding proper roles greatly appreciated :)
Repeat the same for the output lambda function's role also, give it the right S3 permissions.
Try uploading a file again. At this point if you run into this error:
failed to set ACL. INFO NoSuchKey: The specified key does not exist. at Request.extractError. It's because in the bucket you have objects in the protected Folder. Try to use the public folder instead (in the iOS lib you'll have to use StorageAccessLevel.guest permissions to access this)
Now drop a file in the public folder. You should see the MediaConvert job kick off again. It will still fail (check in MediaConvert / Jobs), saying it doesn't have permissions to write to the S3 bucket Unable to write to output file .. . You can fix this by going to the input lambda function again, this gives the permissions to the MediaConvert job:
const jobParams = {
JobTemplate: process.env.ARN_TEMPLATE,
Queue: queueARN,
UserMetadata: {},
Role: process.env.MC_ROLE,
Settings: jobSettings,
};
await mcClient.createJob(jobParams).promise();
Go to the input lambda function, Configuration / Environment Variables. The function uses the field MC_ROLE to provide the role name to the Media Convert job. Copy the role name and look it up in IAM. Modify its permissions by adding the right S3 access to the role to your bucket.
If you try it only more time, the output should appear right next to your input file.
In order to be able to read the s3://public/{userIdentityId}/{videoName}/{videoName}{quality}..m3u8 file using the current Amplify.Storage.downloadFile(key: {key}, ...) function in iOS, you'll probably have to attach to the key right path and remove the .mp4 extension. Let me know if you're facing any problems, I'm sorting this out now also.

EdgeChromium extension chrome.tabs.query failing when only activeTabs permission is requested

I am trying to find the active tabs across all windows, actual query and action is more detailed but this demonstrates the basic problem
chrome.tabs.query({active: true}, function (tabs) { console.log(tabs); });
It seems that with Chrome and Firefox we can use that api with either activeTab or tab permission, only limitations on the search items such as url.
The chrome.tabs or browser.tabs docs only seem to indicate tab permission for some parts.
When using only activeTab permission MS Edge throws error, Chrome gives the result
Adding tabs permission and I can get the results in MS Edge
Is this a deliberate difference, or a bug, or doing something else incorrect?
Trying to ask for minimal permissions as Mozilla and Google required validation of usage with permissions with wide access.
similar to, but not the same as Why browser.tabs.query is not working in Edge Extension ?
first of all, you have to add 'tabs' permission to your manifest file like this
"permissions": [
"tabs"
]
and next use this code
let queryOptions = {
active: true,
currentWindow: true
};
chrome.tabs.query(queryOptions,function (tabs){
alert(tabs[0].url)
});
after that just remove the old extension and load new files in your extensions then observe the permission section in extension details it's should be changed and check it out.

Create google sheets on team drives through API's

Below code creates a google sheet on My Drive but what if I had to place this to a folder on team drive?
I would like to modify createNewSpreadSheet function in such a way that it uploads file to specified folder of team drive.
function createNewSpreadSheet(auth) {
const sheets = google.sheets({version: 'v4', auth});
const resource = {
properties: {
title:'SampleSheet'
},
};
sheets.spreadsheets.create({
resource,
fields: 'spreadsheetId',
}, (err, spreadsheet) =>{
if (err) {
// Handle error.
console.log(err);
} else {
console.log('spreadsheet::',spreadsheet.data.spreadsheetId);
}
});
}
// Load client secrets from a local file.
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Sheets API.
authorize(JSON.parse(content), createNewSpreadSheet);
});
You may check this blog on how to import/upload files to Team Drives folders.
Uploading files to a Team Drives folder is also identical to to uploading to a normal Drive folder, and also done with DRIVE.files().create(). Importing is slightly different than uploading because you're uploading a file and converting it to a G Suite/Google Apps document format, i.e., uploading CSV as a Google Sheet, or plain text or Microsoft Word® file as Google Docs. In the sample app, we tackle the former:
def import_csv_to_td_folder(folder_id, fn, mimeType):
body = {'name': fn, 'mimeType': mimeType, 'parents': [folder_id]}
return DRIVE.files().create(body=body, media_body=fn+'.csv',
supportsTeamDrives=True, fields='id').execute().get('id')
The secret to importing is the MIMEtype. That tells Drive whether you want conversion to a G Suite/Google Apps format (or not). The same is true for exporting. The import and export MIMEtypes supported by the Google Drive API can be found in my SO answer here.

Reading File on Google Drive using Dart

I created a configuration file (Simple Text File) on my Google Drive and now I would like to read it from my Chrome Packaged Dart Application. But I'm not able to get more information of the file than it's name, size etc.
For accessing Google Drive I use the google_drive_v2_api.
Any suggestion on how to get the contents of my configuration file would be great! Thanks!
I just did some test in my own chrome app, uploading and downloading a simple file:
chrome.identity.getAuthToken(new chrome.TokenDetails(interactive: true ))
.then((token){
OAuth2 auth = new SimpleOAuth2(token);
var drive = new gdrive.Drive(auth)..makeAuthRequests=true;
drive.files.insert({},content:window.btoa('hello drive!')).then((sentMeta){
print("File sent! Now retrieving...");
drive.files.get(sentMeta.id).then((repliedMeta){
HttpRequest request = new HttpRequest()..open('GET', repliedMeta.downloadUrl)
..onLoad.listen((r)=>print('here is the result:'+r.target.responseText));
auth.authenticate(request).then((oAuthReq)=>oAuthReq.send());
});
});
});
It works, but the HttpRequest to get content back seems heavy...
But i really recommend you to a take look to chrome.storage.sync if your config file size is < to 4ko... If not, you could also use the chrome SyncFileSystem API... They are both easier to use, and SyncFileSystem use Drive as backend.
This page on downloading files talks through the process for getting the contents of a file.

CouchDB Update XML Attachement

Ive read at least 5 articles on this but I can't seem to get it. I have an xml file that is already in memory in the browser and I am attempting to update a document from my db, for which I already have the doc id. What is the best way of doing this? Is there support for this built into jquery.couch.js, because I can't seem to find any.
Ive attached some code with hard coded values for the sake of my sanity:
var xmlTemp = this.fullscoreApp.MusicXML.document;
$.couch.db("mydb").saveDoc({
"_id": "67e98623efefe16d27e2177b44000aee",
"_rev": "4-830aad7c3dc9e1d5004439ed1c9196d3",
"type":"score",
"_attachments":xmlTemp
}, {
success: function() {
console.log("PLZ");
}
});
I get a DOM 18 error...but I'm using a public server. Thoughts?
What protocol are you using to open your JavaScript file? Are you running it via a webserver (such as http://localhost) or just opening the file (which will show as file:// in the browser)?
If the latter, the browser will report DOM 18, because file:// suffers various restrictions not present for pages served by a webserver. More info from this question.

Resources