Can't see file after uploading it with google drive api - google-api

I want to upload a file using google drvie api. The code returns 200 OK but I can't see the file when I logged in to the google drive in browser.
The credentials.json is generated from a service_account. This account is associated with the google drive api.
The id in parent is copied from the browsers address bar when opened the folder. This folder is also shared with the service account.
const auth = new google.auth.GoogleAuth({
keyFile: 'credentials.json',
scopes: ['https://www.googleapis.com/auth/drive.file'],
});
const drive = google.drive({version: 'v3', auth});
const fileMetadata = {
'name': 'test.txt',
'parents':[{"id":"1yh6V..."}]
};
const media = {
mimeType: 'text/txt',
body: fs.createReadStream('test.txt')
};
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, (err, file) => {
if (err) {
console.error(err);
} else {
console.log('Upload success!');
}
});

It seems you are using Node.js when uploading a file using Drive API, you can use this:
const fileMetadata = {
name: 'test.txt',
parents:["1yh6V..."]
};
const media = {
mimeType: 'text/plain',
body: fs.createReadStream('test.txt')
};
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, (err, file) => {
if (err) {
console.error(err);
} else {
console.log('Upload success!');
}
});
Here are the changes:
Replaced your media.mimeType to 'text/plain' for a plain text file, here are the list of supported Export MIMETypes
Replaced your fileMetadata.parents to ["1yh6V..."], based on this create file in a folder using Node.js where parent property was specified
Note:
Due to my limitation with my environment platforms available, I wasn't able to replicate your issue. I just look for useful references that could help verify your code.

Related

Cypress - How to verify data from a PDF file using cypress command

Below is my code in cypress. How to print 'pdf' content and verify content using cypress .contains or .eq? when I run the code it prints object{6} but I want to print my pdf file content. I would really appreciate the help.
**Plugins/index.js:**
const fs = require('fs')
const pdf = require('pdf-parse')
const path = require('path')
const repoRoot = path.join("C:/Users/XXXXX/Downloads/loginCy-excel")
const parsePdf = async (pdfName) => {
const pdfPathname = path.join(repoRoot, pdfName)
let dataBuffer = fs.readFileSync(pdfPathname);
return await pdf(dataBuffer)
}
module.exports = (on, config) => {
on('task', {
getPdfContent (pdfName) {
return parsePdf(pdfName)
},
})
}
**cypress spec file has these code:**
it('tests a pdf', () => {
cy.task('getPdfContent', 'sample.pdf').then(content => {
cy.log(content)
})
})
pdf method will return an object, so I guess cy.log() can't print it like that. If you want to see what the function gathered in your pdf file, you can stringify the result:
cy
.log(JSON.stringify(content));
If you want to get only text from your pdf, you need to work with text property:
cy
.log(content.text);
Anyone struggling with testing PDF files with cypress can refer to these two very good blog posts precisely on this topic:
https://filiphric.com/testing-pdf-file-with-cypress
https://glebbahmutov.com/blog/cypress-pdf/
It wasn't asked in this question, but here is a little addition from me on how to download files (was tested on PDFs) from a URL:
cy.request({
url: '<file url>',
gzip: false,
encoding: 'base64',
}).then((response) => {
cy.writeFile(
Cypress.config('downloadsFolder') + '/<name of the file>.pdf',
response.body,
{ encoding: 'base64' }
);

drive api - write to shared folder not found

I am using google drive api to write to a folder located in shared drive.
I have created a service account and service account is added to folder with permission as 'content manager'.
However, when I try to use the api to upload file, I keep getting an error stating 'folder not found'.
The same works fine when I try to create a folder onto my personal drive and add service account with 'editor' permission.
Can someone please help me if I missed something or that is as per design?
Below is sample code snippet:
google auth:
const driveauth = new google.auth.JWT(gSuiteUser, null,
JSON.parse(gSuiteKey), [
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive.appdata'
])
const drive = google.drive({
version: 'v3',
auth: driveauth
});
Below is the code for uploading on google drive:
const fileMetadata = {
'name': 'Filename',
'mimeType': 'application/vnd.google-apps.spreadsheet',
parents: [gSuiteFolder],
convert: true
};
const media = {
mimeType: 'text/csv',
body: csvData
};
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, (err, file) => {
if (err) {
// Handle error
console.error(`Failure`);
callback(err);
} else {
console.log('Success', file.data.id);
callback(undefined, "done");
}
});
Turned out that we need to send additional attribute 'supportsAllDrives' as true as shown below:
drive.files.create({
resource: fileMetadata,
media: media,
supportsAllDrives: true,
fields: 'id'
}, (err, file) => {
if (err) {
// Handle error
console.error(`Failure`);
callback(err);
} else {
console.log('Success', file.data.id);
callback(undefined, "done");
}
});
I think something might be off in your deligation.
// loads credentials from .env file
require("dotenv").config();
import { google } from "googleapis";
function initializeDrive(version = "v3") {
const client_email = process.env.GOOGLE_CLIENT_EMAIL;
// add some necessary escaping so to avoid errors when parsing the private key.
const private_key = process.env.GOOGLE_PRIVATE_KEY.replace(/\\n/g, "\n");
// impersonate an account with rights to create team drives
const emailToImpersonate = "some-user#acme-industries.com";
const jwtClient = new google.auth.JWT(
client_email,
null, // undefined if you use TypeScript
private_key,
["https://www.googleapis.com/auth/drive"],
emailToImpersonate
);
return google.drive({
version: version,
auth: jwtClient
});
}
Or maybe a bit more simple
const auth = new google.auth.JWT({ // JWT instead of GoogleAuth
subject: "me#mycompany.com", // include this property
keyFile: "service-account.json",
scopes: [ ... ],
})

Cannot upload image to laravel from react-native

I'm trying to let the user upload an image through react-native, but apparently, laravel is not being able to read any value from the request. This is what I'm trying to do with axios:
const data = new FormData()
data.append('subject_id', this.props.navigation.getParam('id'))
data.append('name', this.state.title)
// I don't think the path is enough, it will probably just send the path as a string instead of the image. You need to load the actual file and append that
data.append('image', {
uri: this.state.image,
type: 'image/jpeg',
name: 'image'
});
data.append('progress', this.state.progress * 100)
data.append('description', this.state.description)
data.append('date', this.state.date)
axios.post('https://example.com/api/auth/storeTask', data, {
headers: {
'Authorization': access,
"Content-Type": "multipart/form-data"
},
}).then(result => { })
.catch(err => console.warn)
The image is not found when I try to access the resource.
You should use a FormData object:
const data = new FormData()
data.append('subject_id', this.props.navigation.getParam('id'))
data.append('name', this.state.title)
// I don't think the path is enough, it will probably just send the path as a string instead of the image. You need to load the actual file and append that
data.append('image', this.state.image)
data.append('progress', this.state.progress * 100)
data.append('description', this.state.description)
data.append('date', this.state.date)
axios.post('https://example.com/api/auth/storeTask', data, {
headers: {
'Authorization': access,
"Content-Type": "multipart/form-data"
},
}).then(result => {})
.catch(err => console.warn)
You didn't send complete info like responses and logs, by the way,
Please check this instruction:
make sure your CSRF in verifyCSRFtoken is allowed
use FormData to upload your file
your code coulde be like this:
import axios, { post } from 'axios';
const url = '/uploadPic';
const formData = new FormData();
formData.append("image", {
name: this.state.photo.fileName,
type: this.state.photo.type,
uri: this.state.photo.uri,
});
const config = {
headers: {
'content-type': 'multipart/form-data'
}
}
const config = {
headers: {
'content-type': 'multipart/form-data'
}
}
return post(url, formData,config)
for react native:
if you are in production and using react-native bare, you should add
<application
...
android:usesCleartextTraffic="true"
...
to your android file.

YouTube search API not filtering embeddable/syndicatable videos

I'm embedding YouTube videos into an app I'm writing, but some of the results are videos that aren't allowed to be played on my site. I've tried setting both videoSyndicated and videoEmbeddable to true in the params but it doesn't seem to fix my problem.
const axios = require('axios');
const ROOT_URL = 'https://www.googleapis.com/youtube/v3/search';
const search = (options, callback) => {
if(!options.key) {
throw new Error('Youtube Search expected key, received undefined');
}
const params = {
type: 'video',
videoEmbeddable: true,
videoSyndicated: true,
part: 'snippet',
key: options.key,
q: options.term,
};
axios.get(ROOT_URL, { params })
.then((response) => {
if(callback) { callback(response.data.items); }
})
.catch((error) => {
console.error(error);
});
};
export default search;`
This looks like a copyright claim by a 3rd party, which happens outside of the YouTube API. You can check this separately by scraping the video page and searching for the copyright text.

how to upload image in register API in strapi?

In defaut registration API, I need to uplaod the image of user in registration API. So how could I manage it ? I'm sending in a formData and it works fine. I can see (binary) in network.
I tried to add image field and it works in admin panel but from API side I tried to send the file in key names like files, profileImage.
I didn't get the error in res. I got success in res.
Issue: When I reload the admin panel, I didn't get user's profile image.
Try this way. I used in react and it works fine for me.
signUpHandler = () => {
console.log("SignUp data ::: ", this.state);
let data = {
username: this.state.signUpForm.username.value,
phone: this.state.signUpForm.phone.value,
email: this.state.signUpForm.email.value,
password: this.state.signUpForm.password.value
}
axios.post('http://0.0.0.0:1337/auth/local/register', data)
.then(res => {
console.log(res);
return res.data.user.id;
})
.then(refId =>{
const data = new FormData();
data.append('files', this.state.selectedFile);
data.append('refId', refId);
data.append('ref', 'user');
data.append('source', 'users-permissions');
data.append('field', 'profileImage');
return axios.post('http://0.0.0.0:1337/upload', data)
})
.then(res =>{
console.log(res);
alert("You registered successfully...");
this.props.history.push('/login');
})
.catch(error =>{
console.log(error);
})
}
First, you will have to customize your user-permission
To do so, you will have to understand this concept: https://strapi.io/documentation/3.0.0-beta.x/concepts/customization.html
Then you will have to find the function you want to update - in your case, the register function.
And tada here it is https://github.com/strapi/strapi/blob/master/packages/strapi-plugin-users-permissions/controllers/Auth.js#L383.
So you will have to create ./extensions/users-permissions/controllers/Auth.js with the same content as the original file.
Then you will have to add
const { parseMultipartData, sanitizeEntity } = require('strapi-utils');
const uploadFiles = require('strapi/lib/core-api/utils/upload-files');
on the top of your file.
And in your function use this
const { data, files } = parseMultipartData(ctx); to parse data and files.
Then you will have to replace ctx.request.body by data to make sure to use the correct data.
After that you will have to add this after the user creation line
https://github.com/strapi/strapi/blob/master/packages/strapi-plugin-users-permissions/controllers/Auth.js#L510
if (files) {
// automatically uploads the files based on the entry and the model
await uploadFiles(user, files, { model: strapi.plugins['users-permissions'].models.user })
}
Solution for Strapi v4:
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer XXXX");
var formdata = new FormData();
formdata.append("files", fileInput.files[0], "XXX.png");
formdata.append("refId", "46");
formdata.append("field", "image");
formdata.append("ref", "plugin::users-permissions.user");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: formdata,
redirect: 'follow'
};
fetch("http://localhost:1337/api/upload", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));

Resources