Access to Google Drive Path

In my attempt to AppleScript a path to a file on a shared Google Drive, I noticed that the path assigned to the file by Google Drive, can vary between users.
On my Mac , the path

/Volumes/GoogleDrive/

permits retrieval of files from the shared Google Drive. On other users’ Macs, where Google Drive is not mounted in the Volumes directory, access to the shared Google drive file requires a path through Cloud Storage, beginning with

/Users/USERNAME/Library/CloudStorage/GoogleDrive-USEReMAIL

Attempting to evaluate Google Drive’s preferences on my Mac, with read defaults

do shell script "defaults read ~/Library/Preferences/com.google.drivefs.settings"

yielded

{
DoNotShowNotifications = “{\“entry\”:[{\“notification_type\”:174},{\“notification_type\”:234},{\“notification_type\”:190},{\“notification_type\”:170},{\“notification_type\”:201}]}”;
PerAccountPreferences = “{\“per_account_preferences\”:[{\“key\”:\“GOOGLEDRIVEkeyA\”,\“value\”:{\“mount_point_path\”:\”/Volumes/GoogleDrive\“,\“mac_smb_port\”:55319,\“enable_smb_spotlight\”:true}},{\“key\”:\“GOOGLEDRIVEkeyB\”,\“value\”:{\“mount_point_path\”:\”/Users/USERNAME/Library/CloudStorage/GoogleDrive-GoogleDrive-USEReMAIL\“}}]}”;
SearchHotKey = SEARCHHOTKey;
}

It appears to me that Google Drive maintains various account mount points, one through the Volumes directory and the other via Library’s Cloud Storage. Although the Google Drive preferences on my Mac contain these two mount points, other users preferences’ mount points only contain a Cloud Storage path.

My goal is to write an AppleScript that can locate the path to a file on this shared Google Drive, regardless of the user’s email address, so that AppleScript will locate a file on any Mac that has access to this shared Google Drive.

1 Like

I’m interested in this too. For now I’m trying Transmit5 and its Google Drive mode.

I have written a script that finds the Google Drive Path from a retuned JSON(?) from the defaults read command of Google Drives Preferences. This will allow the script on multiple users’ Macs and capture their Google Drive account and email information. The script will then construct a pix path so that files on the shared Google Drive can be accessed.

set GoogleDriveLocalPart to "Local-Part" --insert GoogleMailuser name
set GoogleDriveDomainName to "DomainName.com" --insert domaine name referenced by Google Drive


set GoogleDriveFullEmail to GoogleDriveLocalPart & "@" & GoogleDriveDomainName
set GoogleDriveRootPath to my ConstructGoogleDriveRootPathUsingGoogleDriveEmail:GoogleDriveFullEmail

on ConstructGoogleDriveRootPathUsingGoogleDriveEmail:GoogleDriveFullEmail

#	Read  Google Drive Preferences
set jsonString to do shell script "defaults read ~/Library/Preferences/com.google.drivefs.settings"

#	Parse Google Drive's mount point path that corresonds to the GoogleDrive domaine name
set text item delimiters to "mount_point_path"

#	Convert list to text
set jsonStringTextItems to text items of jsonString
repeat with jasonStringItems in jsonStringTextItems
	set jsonStringText to contents of jasonStringItems as string
	
	#	Identifty a string that reflects the user's library path
	if "Users" is in jsonStringText then
		
		#	Get the start of the Google Drive path
		set pathStart to "/Users"
		set text item delimiters to pathStart
		
		#	 Rebuild the GoogleDrive posix path 
		set PathRemainderBlock to text item 2 of jsonStringText
		
		#	Get the end of the Google Drive root path
		set PathEnd to "/GoogleDrive-" & GoogleDriveFullEmail
		
		set text item delimiters to PathEnd
		
		#	Get the remaining middle of the  GoogleDrive posix path
		set PathMiddle to text item 1 of PathRemainderBlock
		
		#	Reconstruct the Posix Path 
		set GoogleDrivePath to pathStart & PathMiddle & PathEnd
		return GoogleDrivePath
	end if
end repeat
GoogleDrivePath
end ConstructGoogleDriveRootPathUsingGoogleDriveEmail:

I tried to script Foundation’s NSJSONSerialization, unsuccessfully with the following code:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set jsonString to do shell script "defaults read ~/Library/Preferences/com.google.drivefs.settings"
set jsonList to (current application's NSJSONSerialization's JSONObjectWithData:((current application's NSString's stringWithString:jsonString)'s dataUsingEncoding:(current application's NSUTF8StringEncoding)) options:0 |error|:(missing value))

As my Foundation’s NSJSONSerialization produced no response, I would like to hear your ideas to decode this Google Drive JSON response

I do not know why I did not see this simple solution earlier. Google’s root directory structure can be accessed via Google Drive’s folder, located in the home folder.

set home to do shell script "echo  $HOME"
set GoogleDrive to home & "/Google Drive/"

Now that I have gained access to Google Drive using the home path & “/Google Drive/”, my following attempt a find a folder, named “Shared”, in that directory failed.

set home to do shell script "echo $HOME"
set GDPath to home & "/Google Drive/"
set findSh to "find " & quoted form of (GDPath) & " -iname " & quoted form of "*Shared*" & " -type d"
do shell script findSh

When I ran the findSh string in Terminal, the command returned an error that the operation was not permitted

find: /Users/alan/Google Drive/: Operation not permitted

I am looking for ways to AppleScript a command to find a folder in Google Drive For Desktop, and I appreciate all ideas.

The simplest way to test the existence of a file or folder is:

set theFolder to ("" & (path to home folder) & "Google Drive:Shared:")
theFolder as alias

Triggers an error if no file/folder exists at this path.

Or an AppleScriptObjC variation:

use framework "Foundation"
use framework "AppKit"
use scripting additions

set thePath to current application's NSHomeDirectory()'s stringByAppendingString:"/Google Drive/Shared/"
set theURL to current application's NSURL's fileURLWithPath:thePath
theURL's checkResourceIsReachableAndReturnError:(missing value)

Returns false if the folder is not found.

Thank you, Ionah. Your idea to use the checkResourceIsReachableAndReturnError instance method confirmed the existence of a file in the Google Drive, and addressed my initial post question.

Now that you answered that question and I can access Google Drive, I would like to find a Google Drive file, whose name I do not completely know but for whom I have several variables.

Prior to Google Drive’s removal of its /Volumes/ mount point, I used a do shell script using unix’s find command. Since the change in Google’s mount point, it appears that Google Drive does not permit such find operation.

Do you have any ideas how to perform a find operation in Google Drive’s new environment, via alternative means?

Could you give an example?

Attempting to use the find shell script in a Directory whose path is composed of my library’s CloudStorage path, using the concatenation of “GoogleDrive” and my GoogleAccountEMailAddress, in the configuration succeeded in finding a file without error.

set TargetDirectory to "/Users/alan/Library/CloudStorage/GoogleDrive-" & GoogleAccountEMailAddress & "/Shared drives/"

set findSh to "find " & quoted form of TargetDirectory & ¬
	space & "-iname" & space & "*" & quoted form of LN & "*" & ¬
	space & "-iname" & space & "*" & quoted form of FN & "*"
set FoundFiles to do shell script findSh

Attempting to perform the same shell script in the TargetDirectory now accessed via “/Users/alan/Library/Google Drive/Shared drives/” yielded “No such file or directory”

set TargetDirectory to "/Users/alan/Google Drive/Shared drives/"

set findSh to "find " & quoted form of TargetDirectory & ¬
	space & "-iname" & space & "*" & quoted form of LN & "*" & ¬
	space & "-iname" & space & "*" & quoted form of FN & "*"
set FoundFiles to do shell script findSh
--> "No such file or directory"

When I used “NSFileManager’s defaultManager()'s contentsOfDirectoryAtURL:” method together with “filteredArrayUsingPredicate:theNSCompoundPredicate” as in the following script, both paths, ie

• “/Users/alan/Library/CloudStorage/GoogleDrive-” & GoogleAccountEMailAddress & “/Shared drives/”

and

• “/Users/alan/Library/Google Drive/Shared drives/”

succeed in finding a file!

The following script succeeded in finding a file with both directory path configurations.

on FindFN:FN LN:LN Directory:DirectoryPath
	set RegularFileKey to current application's NSURLIsRegularFileKey
	set aliasKey to current application's NSURLIsAliasFileKey
	set noPackageContents to current application's NSDirectoryEnumerationSkipsPackageDescendants
	set noHiddenFiles to current application's NSDirectoryEnumerationSkipsHiddenFiles
	
	set fileManager to current application's NSFileManager's defaultManager()
	
	set DirectoryContentsArray to (current application's NSFileManager's defaultManager()'s ¬
		contentsOfDirectoryAtURL:(current application's |NSURL|'s fileURLWithPath:DirectoryPath) ¬
			includingPropertiesForKeys:{} ¬
			options:(noPackageContents + noHiddenFiles) |error|:(missing value))
	
	if DirectoryContentsArray is missing value then return missing value -- otherwise continue script 
	
	set PredicateArray to {LN, FN}
	set NSComparisonPredicateList to {}
	repeat with PredicateItem in PredicateArray
		
		set Predicate to contents of PredicateItem
		set end of NSComparisonPredicateList to (current application's NSPredicate's ¬
			predicateWithFormat:"%K CONTAINS[c] %@" argumentArray:{¬
				"lastPathComponent.stringByDeletingPathExtension", Predicate})
	end repeat
	
	set NSComparisonPredicateArray to current application's NSArray's arrayWithArray:NSComparisonPredicateList
	#	Convert Comparison Predicate array to a Compound Predicate array
	set theNSCompoundPredicate to current application's NSCompoundPredicate's andPredicateWithSubpredicates:NSComparisonPredicateArray
	
	set theNSURLArray to DirectoryContentsArray's filteredArrayUsingPredicate:theNSCompoundPredicate
	return (POSIX path of (theNSURLArray's firstObject() as string))
	
end FindFN:LN:Directory:

I am looking for some insight as to the reasons for the Google Drive path configuration not upsetting to NSFileManager’s defaultManager but throwing an error with the shell’s find command.

  1. Does NSFileManager’s defaultManager view its directory structure differently than the shell?
  2. Does NSFileManager perform a hidden synchronization function to convert between the two Google Drive path configurations, via some type of CloudStorage’s utility?
  3. If so, is there a method to view this function and its results, to manipulate it or to affirm its results with AppleScript?

1 &2: The double slash seems suspect here. Is it a typo in your post or does your script uses this path?
3: Not sure what you mean but contentsOfDirectoryAtURL can’t return a path if the file does not exists.

Your handler could be simplified:

set theFM to current application's NSFileManager's defaultManager()
set theURL to (current application's |NSURL|'s fileURLWithPath:DirectoryPath)
set DirectoryContentsArray to (theFM's contentsOfDirectoryAtURL:theURL includingPropertiesForKeys:{} options:6 |error|:(missing value))

if DirectoryContentsArray is missing value then return missing value -- otherwise continue script 

set thePattern to "lastPathComponent.stringByDeletingPathExtension"
set thePred to (current application's NSPredicate's predicateWithFormat:"%K CONTAINS[c] %@ OR %K CONTAINS[c] %@" argumentArray:{thePattern, FN, thePattern, LN})
set theNSURLArray to DirectoryContentsArray's filteredArrayUsingPredicate:thePred
return (theNSURLArray's valueForKey:"path") as list
return item 1 of (theNSURLArray's valueForKey:"path") as list -- if you only need the fist item

Ionah,
Thanks for finding the double forward slash typographical error, and I have since corrected that error in the original post.
Regarding your simplification of the handler, I appreciate your comments to make it easier.

Regarding the contentsOfDirectoryAtURL method, what perplexes me is that the function returns positive responses in both following path syntaxes.

“/Users/alan/Library/CloudStorage/GoogleDrive-” & GoogleAccountEMailAddress & “/Shared drives/”

“/Users/alan/Library/Google Drive/Shared drives/”

Given this positive response to finding the same URL, ostensibly generated by NSFileManager’s default manager, I wanted to know more about the details of this process, so that I could evaluate NSFileManagers’ underlying approach to this method. Could the generation of the same URL

  1. Arise solely as a Google Drive action in the user’s CloudStarge directory inside the user’s library?
  2. Arise solely from the NSFileManager object?
  3. Arise from some other object or method, of which I am unaware?