How to search file inside a specific folder in google API v3 - java

As i am using v3 of google api,So instead of using parent and chidren list i have to use fileList, So now i want to search list of file inside a specific folder.
So someone can suggest me what to do?
Here is the code i am using to search the file :
private String searchFile(String mimeType,String fileName) throws IOException{
Drive driveService = getDriveService();
String fileId = null;
String pageToken = null;
do {
FileList result = driveService.files().list()
.setQ(mimeType)
.setSpaces("drive")
.setFields("nextPageToken, files(id, name)")
.setPageToken(pageToken)
.execute();
for(File f: result.getFiles()) {
System.out.printf("Found file: %s (%s)\n",
f.getName(), f.getId());
if(f.getName().equals(fileName)){
//fileFlag++;
fileId = f.getId();
}
}
pageToken = result.getNextPageToken();
} while (pageToken != null);
return fileId;
}
But in this method it giving me all the files that are generated which i don't want.I want to create a FileList which will give file inside a specific folder.

It is now possible to do it with the term parents in q parameter in drives:list. For example, if you want to find all spreadsheets in a folder with id folder_id you can do so using the following q parameter (I am using python in my example):
q="mimeType='application/vnd.google-apps.spreadsheet' and parents in '{}'".format(folder_id)
Remember that you should find out the id of the folder files inside of which you are looking for. You can do this using the same drives:list.
More information on drives:list method can be seen here, and you can read more about other terms you can put to q parameter here.

To search in a specific directory you have to specify the following:
q : name = '2021' and mimeType = 'application/vnd.google-apps.folder' and '1fJ9TFZOe8G9PUMfC2Ts06sRnEPJQo7zG' in parents
This examples search a folder called "2021" into folder with 1fJ9TFZOe8G9PUMfC2Ts06sRnEPJQo7zG
In my case, I'm writing a code in c++ and the request url would be:
string url = "https://www.googleapis.com/drive/v3/files?q=name+%3d+%272021%27+and+mimeType+%3d+%27application/vnd.google-apps.folder%27+and+trashed+%3d+false+and+%271fJ9TFZOe8G9PUMfC2Ts06sRnEPJQo7zG%27+in+parents";

Searching files by folder name is not yet supported. It's been requested in this google forum but so far, nothing yet. However, try to look for other alternative search filters available in Search for Files.
Be creative. For example make sure the files within a certain folder contains a unique keyword which you can then query using
fullText contains 'my_unique_keyword'

You can use this method to search the files from google drive:
Files.List request = this.driveService.files().list();
noOfRecords = 100;
request.setPageSize(noOfRecords);
request.setPageToken(nextPageToken);
String searchQuery = "(name contains 'Hello')";
if (StringUtils.isNotBlank(searchQuery)) {
request.setQ(searchQuery);
}
request.execute();

Related

Retrieve last level directory name from path

I have a string that represents a path ... something like this:
/A/B/C/D/E/{id}/{file_name}.ext
The path structure could be different but in general I would like to retrieve last directory name (in the example {id}) before the file-name.
I would like to use Path java class.
Is there a simple and safe way to retrieve last directory name using Path class?
Path#getParent returns a path’s parent. You can then use Path#getFileName:
path.getParent().getFileName();
You could use getName() with File which is available
Reference : https://docs.oracle.com/javase/6/docs/api/java/io/File.html#getName%28%29
File f = new File("C:\\Dummy\\Folder\\MyFile.PDF");
System.out.println(f.getName());
Which returns you MyFile.PDF.
(or)
// Path object
Path path
= Paths.get("D:\\eclipse\\configuration"
+ "\\myconfiguration.conf");
// call getName(int i) to get
// the element at index i
Path indexpath = path.getName(path.getNameCount()-2);
// prints the name
System.out.println("Name of the file : " + indexpath);
Which prints myconfiguration.conf. Hope it helps !

How to get single GridFS file using Java driver 3.7+?

I need to get single the GridFS file using Java driver 3.7+.
I have two collections with file in a database: photo.files and photo.chunks.
The photo.chunks collection contains the binary file like:
The photo.files collection contains the metadata of the document.
To find document using simple database I wrote:
Document doc = collection_messages.find(eq("flag", true)).first();
String messageText = (String) Objects.requireNonNull(doc).get("message");
I tried to find file and wrote in same way as with an example above, according to my collections on screens:
MongoDatabase database_photos = mongoClient.getDatabase("database_photos");
GridFSBucket photos_fs = GridFSBuckets.create(database_photos,
"photos");
...
...
GridFSFindIterable gridFSFile = photos_fs.find(eq("_id", new ObjectId()));
String file = Objects.requireNonNull(gridFSFile.first()).getMD5();
And like:
GridFSFindIterable gridFSFile = photos_fs.find(eq("_id", new ObjectId()));
String file = Objects.requireNonNull(gridFSFile.first()).getFilename();
But I get an error:
java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at project.Bot.onUpdateReceived(Bot.java:832)
at java.util.ArrayList.forEach(ArrayList.java:1249)
Also I checked docs of 3.7 driver, but this example shows how to find several files, but I need single:
gridFSBucket.find().forEach(
new Block<GridFSFile>() {
public void apply(final GridFSFile gridFSFile) {
System.out.println(gridFSFile.getFilename());
}
});
Can someone show me an example how to realize it properly?
I mean getting data, e.g. in chunks collection by Object_id and md5 field also by Object_id in metadata collection.
Thanks in advance.
To find and use specific files:
photos_fs.find(eq("_id", objectId)).forEach(
(Block<GridFSFile>) gridFSFile -> {
// to do something
});
or as alternative, I can find specific field of the file.
It can be done firstly by creating objectId of the first file, then pass it to GridFSFindIterable object to get particular field and value from database and get finally file to convert into String.
MongoDatabase database_photos =
mongoClient.getDatabase("database_photos");
GridFSBucket photos_fs = GridFSBuckets.create(database_photos,
"photos");
...
...
ObjectId objectId = Objects.requireNonNull(photos_fs.find().first()).getObjectId();
GridFSFindIterable gridFSFindIterable = photos_fs.find(eq("_id", objectId));
GridFSFile gridFSFile = Objects.requireNonNull(gridFSFindIterable.first());
String file = Objects.requireNonNull(gridFSFile).getMD5();
But it checks files from photo.files not from photo.chunkscollection.
And I'm not sure that this way is code-safe, because of debug info, but it works despite the warning:
Inconvertible types; cannot cast 'com.mongodb.client.gridfs.model.GridFSFile' to 'com.mongodb.client.gridfs.GridFSFindIterableImpl'

List all files in (sub)directories in Azure

I am developing an azure function using Java. I need to iterate all the files in the following folder
aDirectory/aSubdirectoryWithManyFiles/
There are many files in that path,:
aDirectory/aSubdirectoryWithManyFiles/file1
aDirectory/aSubdirectoryWithManyFiles/file2
aDirectory/aSubdirectoryWithManyFiles/file3
aDirectory/aSubdirectoryWithManyFiles/file4
aDirectory/aSubdirectoryWithManyFiles/file5
so I wrote the following code in order to get them all:
// myCloudBlobContainer is a CloudBlobContainer
// I expected to get all files thanks to the next row
Iterable<ListBlobItem> blobs = myCloudBlobContainer.listBlobs();
// The only blob found in the container is the directory itself
for (ListBlobItem blob : blobs) {
//log the current blob URI
if (blob instanceof CloudBlob) { // this never happens
CloudBlob cloudBlob = (CloudBlob) blob;
//make nice things with every found file
}
}
The only blob iterated in the for is the directory, noone of the expected files. so in logs i get only the following URI:
https://blablablabla.blob.core.windows.net/aDirectory/aSubdirectoryWithManyFiles/
What should I do in order to access every file?
And in case I would have more than one subdirectory, as in the following example?
aDirectory/aSubdirectoryWithManyFiles/files(1-5)
aDirectory/anotherSubdirectoryWithManyFiles/files(6-10)
Thanks in advance
Edit
In order to make methods testable, the project uses wrappers and interfaces instead of directly using directly a CloudBlobContainer; basically, the CloudBlobContainer is given by CloudBlobClient.getContainerReference("containername")
After the answer to this question, I changed teh code to the following
so I used listBlobs with parameters myCloudBlobContainer.listBlobs("aDirectory", true) and I wrote the following code in order to get them all:
// myCloudBlobClient is a CloudBlobClient
CloudBlobContainer myCloudBlobContainer = myCloudBlobClient.getContainerReference("containername")
// I expected to get all files thanks to the next row
Iterable<ListBlobItem> blobs = myCloudBlobContainer.listBlobs("aDirectory", true); // HERE THE CHANGE
// No blob found this time
for (ListBlobItem blob : blobs) { // NEVER IN THE FOR
//log the current blob URI
if (blob instanceof CloudBlob) {
CloudBlob cloudBlob = (CloudBlob) blob;
//make nice things with every found file
}
}
But this time, it doesn't go at all in the for...
I must say that the previous answer made me to waste time; the problem was in the fact that only one for is not enough to find files in folders. The first for finds the folders and subfolders, plus (maybe, i didn't check) files that are in the "root" (let's call it like that).
Having the folders, for each of them we have to cast as CloudBlobDirectory in order to see and iterate all contained files with another for.
Here the solution that works for me:
// myCloudBlobClient is a CloudBlobClient
CloudBlobContainer myCloudBlobContainer = myCloudBlobClient.getContainerReference("containername")
// I expected to get all files thanks to the next row
Iterable<ListBlobItem> blobs = myCloudBlobContainer.listBlobs();
// only directories here, another for needed to scan files
for (ListBlobItem blob : blobs) {
if (blob instanceof CloudBlobDirectory) {
CloudBlobDirectory directory = (CloudBlobDirectory)blob;
//next is in try/catch
Iterable<ListBlobItem> fileBlobs = directory.listBlobs();
for (ListBlobItem fileBlob : fileBlobs) {
if (fileBlob instanceof CloudBlob) {
CloudBlob cloudBlob = (CloudBlob) fileBlob;
//make nice things with every found file
}
}
} // else: may be we found a cloudBlob in root?
}
This helped me to find the right way:
https://social.msdn.microsoft.com/Forums/en-US/1cfdc91f-e588-4839-a878-9650339a0a06/list-all-blobs-in-c?forum=windowsazuredata
Try using the following override of listBlobs method:
listBlobs(String prefix, boolean useFlatBlobListing)
So your code would be:
Iterable<ListBlobItem> blobs = myCloudBlobContainer.listBlobs("aDirectory", true);
This will list all blobs inside "aDirectory" virtual folder in your blob container.

IMAP List extension JAVA

I'm building a tool that need access to mail specific folders (e.g. '[Gmail]/Trash', '[Gmail]/Sent'). It seems that the names are localized with respect to the user localization settings, so '[Gmail]/Trash' show as '[Gmail]/Papelera' to Spanish users for example.
I read about XLIST command but now is deprecated in favor of the IMAP LIST Extension (https://developers.google.com/gmail/imap_extensions#special-use_extension_of_the_list_command).
I tried to do it that way javax.mail.Folder.list("\Trash") but nothing is returned.
How can I use the IMAP List extension in JAVA?
PS: Using several email providers, not just Gmail.
As Bill Shannon said, You can use Gmail attributes to get special folders like Trash. But this will work only with Gmail.
javax.mail.Folder[] folders = store.getDefaultFolder().list("*");
If you print this, it should look like the following as per Gmail
a004 LIST "" "*"
* LIST (\HasNoChildren) "/" "INBOX"
* LIST (\Noselect \HasChildren) "/" "[Gmail]"
* LIST (\HasNoChildren \All) "/" "[Gmail]/All Mail"
* LIST (\HasNoChildren \Drafts) "/" "[Gmail]/Drafts"
* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important"
* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam"
* LIST (\HasNoChildren \Flagged) "/" "[Gmail]/Starred"
* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash"
a004 OK Success
Once you have the folders with you, you can iterate for the attribute you are looking for.
For [Gmail]/All Mail, mailFolder = "\\All". similarly for [Gmail]/Trash it will be mailFolder = "\\Trash"
private static IMAPFolder getLocalisedFolder(IMAPStore store, String mailFolder) throws MessagingException {
Folder[] folders = store.getDefaultFolder().list("*");
for (Folder folder : folders) {
IMAPFolder imapFolder = (IMAPFolder) folder;
for (String attribute : imapFolder.getAttributes()) {
if (mailFolder.equals(attribute)) {
return imapFolder;
}
}
}
return null;
}
This should help:
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getDefaultInstance(props, null);
javax.mail.Store store = session.getStore("imaps");
store.connect("imap.gmail.com", "myemail#gmail.com", "mypassword");
javax.mail.Folder[] folders = store.getDefaultFolder().list("*");
for (javax.mail.Folder folder : folders) {
if ((folder.getType() & javax.mail.Folder.HOLDS_MESSAGES) != 0) {
System.out.println("foldername->"+folder.getFullName() + " folder msg count->" + folder.getMessageCount());
}
}
} catch (MessagingException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
You say you tried this:
javax.mail.Folder.list("\Trash")
Try without the slash:
javax.mail.Folder.list("Trash")
See how it goes. Now that's assuming that the folder is actually called "Trash". If it's localised in some other language, then you probably need to list all folders ("*"), iterate through them one by one, and find the one that gave you the \Trash attribute. I'm not very familiar with JavaMail so I don't know whether/how it gives you back the folder attributes.
maybe you can check (once you have a Folder folder) if
if ((folder.getType() & Folder.HOLDS_MESSAGES) != 0) {
and then check if messages in the folder have this flag:
Flags.Flag.DELETED
if so, that would mean this is the Trash? I don't remmeber if when a msg is deleted it is moved to the Trash or it can remain in the folder...if it is moved, that could make the trick.
Gmail no longer requires the use of the XLIST command. Gmail returns attributes with the regular IMAP LIST command that indicate the use of the localized mailboxes. You can access these attributes using the IMAPFolder.getAttributes method.
I'm afraid that doesn't help you if you have another IMAP server that only returns this information with XLIST.

Copying Google Docs documents with Java GWT

According to the Google Documents List Data API there is an option to copy documents:
http://code.google.com/apis/documents/docs/3.0/developers_guide_protocol.html#CopyingDocs
But when I look in the GWT Java docu of the API, this menu point is missing.
http://code.google.com/apis/documents/docs/3.0/developers_guide_java.html
Do you know, if there is a method to copy GDocs documents in the Java GWT API? Which maybe is just not documented?
Looking in the python API I find the python method:
http://code.google.com/apis/documents/docs/3.0/developers_guide_python.html#CopyingDocs
I now managed to write my own copy request:
Replace t7Z3GLNuO641hOO737UH60Q by the documents key, you like to copy
String = "new File";
String userEmail= new CurrentUser ().getUser ().getEmail ();
String body = "<?xml version='1.0' encoding='UTF-8'?>"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<id>t7Z3GLNuO641hOO737UH60Q</id>"
+ "<title>"+ title +"</title>"
+ "</entry>";
try {
GDataRequest gdr = docsService.createRequest(Service.GDataRequest.RequestType.INSERT,
new URL("https://docs.google.com/feeds/default/private/full/?xoauth_requestor_id="+ userEmail),
ContentType.ATOM);
gdr.setHeader("GData-Version", "3.0");
OutputStream requestStream = gdr.getRequestStream();
requestStream.write(body.getBytes());
log.info(gdr.toString());
gdr.execute();
}
[.. catch]

Categories