Good afternoon. I am currently working on a project and I need to use python to get all the image_ids of the images in a folder. I have tried to use
query = f"parents = '{folder_id}'"
files = service.files().list(q=query).execute()
but for some reason this returns an id which is different to the real image id you can find in drive. Any tips?
Answer:
Your query parameter is malformed.
More Information:
The q parameter needs to be rewritten as:
'folderId' in parents and mimeType='image/jpeg'
where folderId is the ID of the folder in which you wish to search.
The q parameter allows you to specify properties of the files you are trying to list - so you're saying here "List all files that have a mimetype of image/jpeg, where folderId is contained in its list of parents."
Im suprised that works at all since parents use in not =
Example
To return all the files in the folder.
parents in '{folder_id}'
This would give you all the jpeg files on your drive
mimeType='image/jpeg'
You can put them both together using and
parents in 'root' and mimeType='image/jpeg'
Related
I want to use PyGSheets to create a Spreadsheet in my Google Drive folder. I also want to be able to set the directory/folder where the sheet is created using the code. Specifically, I would like to type a string similar to a URL or even just the folder's name.
I have already looked at the PyGSheets documentation and the "Spreadsheet" model. I have not found any classes that accept a folder name or directory address. There is also no class used to move a sheet from one folder to another. Is either operation possible using PyGSheets?
As of May 5, I have used a work-around for this problem. To get the ID of a folder in my Drive, I right-click the target folder and select "Get shareable link" from the menu that appears. I copy the link and paste it on any text editor. The link looks like this: https://drive.google.com/open?id=9JHS74hgls049J50. I copy the random string of characters after the "id = " keywords. That is what I supply as a value when I create a folder using PyGSheets:
shtTargetedCreate = con.create("Test Folder",folder="1GwA4W8iv-26BvG48nKnEigYqDL8SpUGK")
Is there any more efficient way to do this?
Well it looks like you figured out how to create a new spreadsheet in a folder by file id, but haven't found how to get folder names / IDs from within pygsheets or how to move sheets. (You said you created a "folder using PyGSheets, but that just creates a spreadsheet, right?)
These can both be done by using the DriveAPIWrapper functions - https://pygsheets.readthedocs.io/en/stable/drive_api.html
Folder names / IDs:
pygsheets.drive.list(), in your case con.drive.list(), will give a list of metadata dictionaries for all files and folders in the drive. I've made a simple function to extract just the folder names (keys) and ids (values) into a dictionary for simpler lookup and use with the create method:
def folder_id_dict(client):
folders = {}
meta_list = client.drive.list()
for file_meta in meta_list:
if file_meta['mimeType'] == 'application/vnd.google-apps.folder':
folders[file_meta['name']] = file_meta['id']
return folders
#your use:
names = folder_id_dict(con)
Moving files between folders:
https://pygsheets.readthedocs.io/en/stable/drive_api.html#pygsheets.drive.DriveAPIWrapper.move_file
con.drive.move_file(file_id, old_folder, new_folder, **kwargs)
I need to upload some 2000 documents to specific users in salesforce. I have a csv file that has the Salesforce-assigned ContactID, as well as a direct path to the files on my desktop. Each contact's specific file url has been included in the csv. How can I upload them all at one and, especially, to the correct contact?
You indicated in the comments / chat that you want it as "Files".
The "Files" object is bit more complex than Attachments, you'll need to do it in 2-3 steps. What you see as a File (you might see it referred to in documentation as Chatter Files or Salesforce Content) is actually several tables. There's
ContentDocument which can be kind of a file header (title, description, language, tags, linkage to many other areas in SF - because it can be standalone, it can be uploaded to certain SF Content Library, it can be linked to Accounts, Contacts, $_GOD knows what else)
ContentVersion which is well, actual payload. Only most recent version is displayed out of the box but if you really want you can go back in time
and more
The crap part is that you can't insert ContentDocument directly (there's no create() call in the list of operations) .
Theory
So you'll need:
Insert ContentVersion (v1 will automatically create for you parent ContentDocuments... it does sound bit ass-backwards but it works). After this is done you'll have a bunch of standalone documents loaded but not linked to any Contacts
Learn the Ids of their parent ContentDocuments
Insert ContentDocumentLink records that will connect Contacts and their PDFs
Practice
This is my C:\stacktest folder. It contains some SF cheat sheet PDFs.
Here's my file for part 1 of the load
Title PathOnClient VersionData
"Lightning Components CheatSheet" "C:\stacktest\SF_LightningComponents_cheatsheet_web.pdf" "C:\stacktest\SF_LightningComponents_cheatsheet_web.pdf"
"Process Automation CheatSheet" "C:\stacktest\SF_Process_Automation_cheatsheet_web.pdf" "C:\stacktest\SF_Process_Automation_cheatsheet_web.pdf"
"Admin CheatSheet" "C:\stacktest\SF_S1-Admin_cheatsheet_web.pdf" "C:\stacktest\SF_S1-Admin_cheatsheet_web.pdf"
"S1 CheatSheet" "C:\stacktest\SF_S1-Developer_cheatsheet_web.pdf" "C:\stacktest\SF_S1-Developer_cheatsheet_web.pdf"
Fire Data Loader, select Insert, select showing all Salesforce objects. Find ContentVersion. Load should be straightforward (if you're hitting memory issues set batch size to something low, even 1 record at a time if really needed).
You'll get back a "success file", it's useless. We don't need the Ids of generated content versions, we need their parents... Fire "Export" in Data Loader, pick all objects again, pick ContentDocument. Use query similar to this:
Select Id, Title, FileType, FileExtension
FROM ContentDocument
WHERE CreatedDate = TODAY AND CreatedBy.FirstName = 'Ethan'
You should see something like this:
"ID","TITLE","FILETYPE","FILEEXTENSION"
"0690g0000048G2MAAU","Lightning Components CheatSheet","PDF","pdf"
"0690g0000048G2NAAU","Process Automation CheatSheet","PDF","pdf"
"0690g0000048G2OAAU","Admin CheatSheet","PDF","pdf"
"0690g0000048G2PAAU","S1 CheatSheet","PDF","pdf"
Use Excel and magic of VLOOKUP or other things like that to link them back by title to Contacts. You wrote you already have a file with Contact Ids and titles so there's hope... Create a file like that:
ContentDocumentId LinkedEntityId ShareType Visibility
0690g0000048G2MAAU 0037000000TWREI V InternalUsers
0690g0000048G2NAAU 0030g000027rQ3z V InternalUsers
0690g0000048G2OAAU 0030g000027rQ3a V InternalUsers
0690g0000048G2PAAU 0030g000027rPz4 V InternalUsers
1st column is the file Id, then contact Id, then some black magic you can read about & change if needed in ContentDocumentLink docs.
Load it as insert to (again, show all objects) ContentDocumentLink.
Woohoo! Beer time.
Your CSV should contain following fields :
- ParentID = Id of object you want to link the attachment to (the ID of the contact)
- Name = name of the file
- ContentType = extension(.xls or .pdf or ...)
- OwnerId = if empty I believe it takes your user as owner
- body = the location on your machine of the file (for instance: C:\SFDC\Files\test.pdf
Use this csv to insert the records (via data loader) into the Attachment object.
You will then see for each contact, that records have been added to the 'Notes & Attachments' related list.
The query string in try it section does not work 12 hours ago.
My query string is mimeType = 'application/vnd.google-apps.folder'
Anyway not work with any query.
https://developers.google.com/drive/v2/reference/children/list
Please tellme why??
I'm having the same issue:
child.Q = "mimeType = 'application/vnd.google-apps.folder' and title contains 'SomeDocuments'"
Dim cl As ChildList = child.Fetch
it returns all the documents like there was no filter
Maybe something change on Google Drive API?
Update
I can't find anything from Google, I wrote a feedback in the child list page.
The only workaround so far is instead of using the children.list use the file.list method and in the q section add the - 'folderid' in parents - search term to emulate searching on childrens of the parent folder.
The drawback is it will only search for document that has folderid as parent, not sub-folders like children.list method do.
Update 2
Looks like Google fixed it!
Happy coding.
I have a list of file ids that I want to refresh with up-to-date metadata. I know there is a file/get method that I could call for each file, but it's obviously not the right way to deal with it if we have many files.
So I've looked for the file/list and its "q" parameter to make a search query. Unfortunately, it looks like it doesn't accept the "id IN (?, ?)" format.
So is there a clever way to do this?
You could wrap all of the file/get/put calls into a single batch.
https://developers.google.com/google-apps/documents-list/#batching_resource_operations_into_a_single_request
You can add all those files to a specific folder and then search for them using the parents field of a search query, as in:
'1234567' in parents
that returns all files that are contained in the folder with ID 1234567.
Is there a reason you need to download the items before you update them?
Given you have the file ID, you can simply PUT your changes.
It appears that listing the children of a folder doesn't actually return the titles of said children according to the Google Drive documentation.
Do I have to query using the id of every single child to determine the name of the file/folder?
Thanks!
EDIT:
Just occurred to me, is the way around this to do a search where the parent id is equal to the folder id I want to see the contents of?
You are absolutely correct, listing the children of a folder only gives you their ids, so you have to send other queries to retrieve titles and the other metadata. I agree this is not optimal and we are considering making some changes here to improve the developer experience.
In the meanwhile, I'd recommend adopting your workaround and search for those files whose parent is the folder you want to see the contents of.
If anyone is still looking at how to get the title of a folders children assuming you already have the children(fileId) id's
function getFileProps(fileId, callback) {
var request = gapi.client.drive.files.get({
'fileId': fileId
});
request.execute(function (resp) {
callback(resp);
});
}
You should use query params for files.list() method for getting that results,
In my example in Python it was:
service.files().list(maxResults=1000, q="'{0}' in parents".format(root_id)).execute()
all query params you could see this link: