Empty Shared with me Folder in Google Drive? - google-api

I want to Empty Share with me folder How can I empty It is My Code and I am using Google Drive V3 .
service.Permissions.Delete(PermissionID, fileId).Execute();
service.Files.Delete(fileId).Execute();
Both line gives a permission 403 error.
If I delete MyDrive file that time Second line he worked fine but Shared With me Folder not Deleted

The thing you need to remember is that Share with me is not a file you actually own that is why this didn't work.
service.Files.Delete(fileId).Execute();
First Get a list of all files in Share with me folder.
var request = service.Files.List();
request.Q = "(sharedWithMe = true)";
request.Fields = "*";
var results = request.Execute();
Find the file you wish to delete:
var myfile = results.Files.Where(a => a.Name.ToLower().Equals("receipt.pdf")).FirstOrDefault();
Now find the permissions on that file associated with the current authenticated user:
var per = myfile.Permissions.Where(a => a.EmailAddress.ToLower().Equals("xxxxx#gmail.com")).FirstOrDefault();
Delete the permissions from the mail file.
service.Permissions.Delete(myfile.Id, per.Id).Execute();
I tested it and it worked. You can just run the initial request though a loop and delete everything if you wish.
Note: This does not appear to work in all cases. I have a file on my Google drive that was shared with me by what appears to be a service account. I have no permissions on the file there for i cant remove my access. I am still digging.

Related

Xamarin Android share PDF. Permission denied for the attachment [duplicate]

My app creates mails with attachments, and uses an intent with Intent.ACTION_SEND to launch a mail app.
It works with all the mail apps I tested with, except for the new Gmail 5.0 (it works with Gmail 4.9), where the mail opens without attachment, showing the error: "Permission denied for the attachment".
There are no useful messages from Gmail on logcat. I only tested Gmail 5.0 on Android KitKat, but on multiple devices.
I create the file for the attachment like this:
String fileName = "file-name_something_like_this";
FileOutputStream output = context.openFileOutput(
fileName, Context.MODE_WORLD_READABLE);
// Write data to output...
output.close();
File fileToSend = new File(context.getFilesDir(), fileName);
I'm aware of the security concerns with MODE_WORLD_READABLE.
I send the intent like this:
public static void compose(
Context context,
String address,
String subject,
String body,
File attachment) {
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("message/rfc822");
emailIntent.putExtra(
Intent.EXTRA_EMAIL, new String[] { address });
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
emailIntent.putExtra(
Intent.EXTRA_STREAM,
Uri.fromFile(attachment));
Intent chooser = Intent.createChooser(
emailIntent,
context.getString(R.string.send_mail_chooser));
context.startActivity(chooser);
}
Is there anything I do wrong when creating the file or sending the intent? Is there a better way to start a mail app with attachment? Alternatively - has someone encountered this problem and found a workaround for it?
Thanks!
I was able to pass a screenshot .jpeg file from my app to GMail 5.0 through an Intent. The key was in this answer.
Everything I have from #natasky 's code is nearly identical but instead, I have the file's directory as
context.getExternalCacheDir();
Which "represents the external storage directory where you should save cache files" (documentation)
GMail 5.0 added some security checks to attachments it receives from an Intent. These are unrelated to unix permissions, so the fact that the file is readable doesn't matter.
When the attachment Uri is a file://, it'll only accept files from external storage, the private directory of gmail itself, or world-readable files from the private data directory of the calling app.
The problem with this security check is that it relies on gmail being able to find the caller app, which is only reliable when the caller has asked for result. In your code above, you do not ask for result and therefore gmail does not know who the caller is, and rejects your file.
Since it worked for you in 4.9 but not in 5.0, you know it's not a unix permission problem, so the reason must be the new checks.
TL;DR answer:
replace startActivity with startActivityForResult.
Or better yet, use a content provider.
Use getExternalCacheDir() with File.createTempFile.
Use the following to create a temporary file in the external cache directory:
File tempFile = File.createTempFile("fileName", ".txt", context.getExternalCacheDir());
Then copy your original file's content to tempFile,
FileWriter fw = new FileWriter(tempFile);
FileReader fr = new FileReader(Data.ERR_BAK_FILE);
int c = fr.read();
while (c != -1) {
fw.write(c);
c = fr.read();
}
fr.close();
fw.flush();
fw.close();
now put your file to intent,
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
You should implement a FileProvider, which can create Uris for your app's internal files. Other apps are granted permission to read these Uris. Then, simply instead of calling Uri.fromFile(attachment), you instantiate your FileProvider and use:
fileProvider.getUriForFile(attachment);
Google have an answer for that issue:
Store the data in your own ContentProvider, making sure that other apps have the correct permission to access your provider. The preferred mechanism for providing access is to use per-URI permissions which are temporary and only grant access to the receiving application. An easy way to create a ContentProvider like this is to use the FileProvider helper class.
Use the system MediaStore. The MediaStore is primarily aimed at video, audio and image MIME types, however beginning with Android 3.0 (API level 11) it can also store non-media types (see MediaStore.Files for more info). Files can be inserted into the MediaStore using scanFile() after which a content:// style Uri suitable for sharing is passed to the provided onScanCompleted() callback. Note that once added to the system MediaStore the content is accessible to any app on the device.
Also you can try set permissions for your file:
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
And finally you can copy/store your files in external storage - permissions not needed there.
I tested it and I found out that it was definitely private storage access problem.
When you attach some file to Gmail (over 5.0) do not use the file from private storage such as /data/data/package/. Try to use /storage/sdcard.
You can successfully attach your file.
Not sure why GMail 5.0 doesn't like certain file paths (which I've confirmed it does have read access to), but an apparently better solution is to implement your own ContentProvider class to serve the file. It's actually somewhat simple, and I found a decent example here: http://stephendnicholas.com/archives/974
Be sure to add the tag to your app manifest, and include a "android:grantUriPermissions="true"" within that. You'll also want to implement getType() and return the appropriate MIME type for the file URI, otherwise some apps wont work with this... There's an example of that in the comment section on the link.
I was having this problem and finally found an easy way to send email with attachment. Here is the code
public void SendEmail(){
try {
//saving image
String randomNameOfPic = Calendar.DAY_OF_YEAR+DateFormat.getTimeInstance().toString();
File file = new File(ActivityRecharge.this.getCacheDir(), "slip"+ randomNameOfPic+ ".jpg");
FileOutputStream fOut = new FileOutputStream(file);
myPic.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
//sending email
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"zohabali5#gmail.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Recharge Account");
intent.putExtra(Intent.EXTRA_TEXT, "body text");
//Uri uri = Uri.parse("file://" + fileAbsolutePath);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(Intent.createChooser(intent, "Send email..."),12);
}catch (Exception e){
Toast.makeText(ActivityRecharge.this,"Unable to open Email intent",Toast.LENGTH_LONG).show();
}
}
In this code "myPic" is bitmap which was returned by camera intent
Step 1: Add authority in your attached URI
Uri uri = FileProvider.getUriForFile(context, ""com.yourpackage", file);
Same as your manifest file provide name
android:authorities="com.yourpackage"
Step 2`; Add flag for allow to read
myIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

Read the word document content from google drive

I am trying fetch doc content from google drive using the Google sdk. The problem is, the get() function is not working properly. It gives only file metadata not any actual content.
$googl = new Googl();
$this->client = $googl->client();
$this->client->setAccessToken(session('user.token'));
$this->drive = $googl->drive($this->client);
$file = $this->drive->files->get("fileId");
return $file;
From the documentation it looks like you can download a file using:
$file = $this->drive->files->get("fileId", array('alt' => 'media'));
$content = $file->getBody()->getContents();
I suspect that we may have a language issue here.
Read the content from a Google drive file
The google drive api is a file datastore api. This means that it stores the file itself and the information about said file. It does not give you any access to the contents of that file.
If you want to know what is in the file you will need to download the file and open it up on your machine.
or try Google documents api however i suspect that it will only be able to read a google drive document file and not a word file you may have to convert it first.
download the the file
If you check the documentation for Download Files you will find the following.
$fileId = '0BwwA4oUTeiV1UVNwOHItT0xfa2M';
$response = $driveService->files->get($fileId, array(
'alt' => 'media'));
$content = $response->getBody()->getContents();

I can not see the image I just uploaded [sails.js]

I have this to upload photos:
module.exports = function (req, image, url, callback) {
var filename = (Math.floor((Math.random() * 100000000000) + 1)) + ".png";
req.file(image).upload({
dirname: '../../assets/images' + url
,
saveAs: function(file, cb) {
cb(null, filename);
}
}, function(error, uploadedFiles) {
return callback(null, "http://" + req.headers.host + "/images" + url + filename)
});
}
And it returns an url like this: http://localhost:1349/images/dependent/photos/30363010266.png
I can see that my photo is uploaded in project folder because I see it physically. But the URL do not work and has appeared not found error.
If I restart server, the URL works fine.
Thanks!
As #Eugene Obrezkov pointed out, your issue is related to where you are uploading your images and the grunt task runner. All the assets are copied from that folder (/assets) to the .tmp, and changes are watched by the grunt task runner, but that doesn't include new image files(If you are to an empty folder in the assets folder, in your case to the image folder). So the solution is quite easy, you must upload directly to the .tmp folder, ideally to .tmp/public/uploads/year/month/, you can choose your path as you see fit. Now there is a caveat with this approach, and it is that there is a grunt task that clears the contents of the .tmp folder on sails lift, so you will get the opposite effect, now to avoid this is quite easy too, you must edit the clean.js task to delete specific folders, to avoid deleting your uploads folder.
Go to to your project folders tasks/config/clean.js, and replace what's in there for this code, or modify it as you need.
module.exports = function(grunt) {
grunt.config.set('clean', {
dev: [
getFolderPath('fonts/**'),
getFolderPath('images/**'),
getFolderPath('images/**'),
getFolderPath('js/**'),
getFolderPath('styles/**'),
getFolderPath('*.*')
],
build: ['www']
});
grunt.loadNpmTasks('grunt-contrib-clean');
};
function getFolderPath(folderName){
return '.tmp/public/' + folderName;
}
Now your uploads will appear immediately to your end-user without restart, and restarts won't delete those uploads. Just make sure the .tmp/public/uploads/ path exist before trying to upload, or use mkdir to create it via code if not found.
There are other solutions, like making sure there is at least a file in the folder you are uploading to when the server starts, or using symlinks, but i think this is a cleaner approach. You can check those options here:
Image not showing immediately after uploading in sails.js
If you take a look into tasks folder, you can find Grunt task that copies all the assets folder to .tmp folder and make .tmp folder as static public folder.
When you are running Sails application, it runs these Grunt tasks, so that if you uploading file direct to assets folder it will not be accessible until you re-run server and Grunt tasks.
Solution? There is no solution. Basically, you are doing it wrong. Best practices is to store images\files\whatever on S3 buckets, Google Storage, another hard drive at least, but not assets itself. Because it's your source files of your project and in there should be located only files needed for project itself, not user's files, etc...
You can achieve without modifing any grunt task. I had the same issue and I have just solved it.
I see you already have an explanation of what's happening in other comments, so I'll go straight to my solution. I uploaded the files to the .tmp folder, and on the callback of the upload, I coppied them to the assets folder using the file system (fs-extra is a great package for that).
So now I can see the images in my UI as soon as it's added (cause I uploaded them to .tmp) and when my server stops, .tmp will be lost, but generated again in the next lift with the files copied to assets.
Hope it helps!
This is how I solved this problem. The answer requires several steps. I am assuming you want to place your recently uploaded images in a folder called users.
Steps:
1. npm install express --save (If you don't have it installed)
Create a Users folder in your apps root directory.
Open the text editor and view the following file config\express.js
Add or replace with the code
`
var express = require('express');
module.exports.http = {
customMiddleware: function (app) {
app.use('/users', express.static(process.cwd() + '/users'));
}
};
`
5. Make certain the newly uploaded images are placed in the Users folder
Finish

How to download file from google drive api with service account?

Hello google hackers!
I am using Drive Service app and uploaded file successfully like this:
require 'googleauth'
require 'google/apis/drive_v2'
Drive = Google::Apis::DriveV2
upload_source = "/User/my_user_name/hacking.txt"
drive = Drive::DriveService.new
# Drive::AUTH_DRIVE is equal to https://www.googleapis.com/auth/drive
drive.authorization = Google::Auth.get_application_default([Drive::AUTH_DRIVE])
file = drive.insert_file({title: 'hacking.txt'}, upload_source: upload_source)
file has a lot of properties, like this:
download_url
But when I try to open this download_url in browser it shows me blank screen. Why I can't download it?
I guess, that may be there are permission problems? But the scope is correct, and uploading is successful...
The answer is simple - we cannot download it from file object, we must send another get request, just download it like this:
drive.get_file(file.id, download_dest: '/tmp/my_file.txt')

Is it possible to upload image or file to SkyDrive fom Metro Style App?

Is it possible to upload image or file to SkyDrive fom Metro Style App?
I have already found how to browse the file from SkyDrive. But I haven't found regarding uploading file to SkyDrive. If you reply me, it will be very thankful..
I don't think the file picker method works unless the user has the desktop app installed.
You should use a Sharing contract. If you add a data file (Storage Item) to share, then SkyDrive will be listed as a share target and the user gets a UI where they can choose where in their SkyDrive they want to save. This is how I implemented it in my app.
For more info...
http://msdn.microsoft.com/en-us/library/windows/apps/hh771179.aspx
You can use FileSavePicker to save files. This will of course give the user a chance to select where he wants to save to local documents folder or sky drive. The user is in control.
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
savePicker.DefaultFileExtension = ".YourExtension";
savePicker.SuggestedFileName = "SampleFileName";
savePicker.FileTypeChoices[".YourExtension"] = new List<string>() { ".YourExtension"};
StorageFile file = await savePicker.PickSaveFileAsync();
if (file != null)
{
await FileIO.WriteTextAsync(file, "A bunch of text to save to the file");
}
Please note that in the sample code I am creating the content of the file in code. If you want the user to select an existing file from the computer then you will have to first use FileOpenPicker, get the file and then use FileSavePicker to save the contents of the selected file to the SkyDrive
Assuming that you are using XAML/JavaScript, the suggested solution is to use FilePicker.
The following link may help you.
http://msdn.microsoft.com/en-us/library/windows/apps/jj150595.aspx
Thanks Mamta Dalal and Dangling Neuron, but there is problem. But it looks like I can't use FileSavePicker. I have to upload file(documnet, photo) not only text file. I have to copy from one path to another. If I use FileSavePicker, I have to write every file content (text, png, pdf, etc) and can't copy. Currently I am using FolderPicker. But unfortunately, FolderPicker doesn't support SkyDrive.My Code is As follow:
>FolderPicker saveFolder = new FolderPicker();
>saveFolder.ViewMode = PickerViewMode.Thumbnail;
>saveFolder.SuggestedStartLocation = PickerLocationId.Desktop;
>saveFolder.FileTypeFilter.Add("*");
>StorageFolder storagefolderSave = await saveFolder.PickSingleFolderAsync();
>StorageFile storagefileSave = [Selected storagefile with file picker];
>await storagefileSave.CopyAsync(storagefolderSave,storagefileSave.Name,NameCollisionOption.ReplaceExisting);
It will be greate that if FolderPicker supports SkyDrive or can copy file using FileSavePicker.

Resources