copy / paste network paths - paste command opens new finder

Hey everyone,

This is a script we had at my old job that I’m having trouble implementing at the new. We’re a digital production house so our file server is quite large with lots and lots of directories and sub folders. What this allowed us to do was copy / paste network paths to files and folders via chat and once a viable network path is in a users clipboard, utilize the script to open up a new finder window with the specified directory.

These scrips were integrated with a program called Fast Scripts which allows you to map short cut keys to call a script. So for example, my map was option + command + c to copy a file path. Once I had a file path in my clipboard I would use option + command + v while in finder and a new finder window would come up at that file’s location. Ideally this script is dynamic so all can utilize without rewording/writing the apple script to suit their network shares. Appreciate any help you can lend, I’d like to add this to the library once complete.

This is the copy path script:


tell application "Finder"
	set selectedPath to (POSIX path of (the selection as alias))
	set thePath to selectedPath
	set AppleScript's text item delimiters to "/"
	set selectedPathItems to text items of selectedPath
	if text item 2 of selectedPathItems = "Volumes" then
		set workPath to (text 1 thru 4 of text item 3 of selectedPathItems) as string
		if workPath = "buzzsaw" then
			set AppleScript's text item delimiters to "Volumes"
			set thePathItems to text items of selectedPath
			set AppleScript's text item delimiters to "buzzsaw"
			set thePath to thePathItems as text
			set AppleScript's text item delimiters to "/"
			set thePathItems to text items of thePath
			set (text item 3 of thePathItems) to "WoodShop_Projects"
			set thePath to text items of thePathItems as string
			set AppleScript's text item delimiters to ""
		end if
	end if
	set AppleScript's text item delimiters to "/"
	set thePathItems to text items of thePath
	set AppleScript's text item delimiters to "\\"
	set thePath to thePathItems as text
	set AppleScript's text item delimiters to ""
	set selectedPath to ("\\" & thePath)
	set the clipboard to the selectedPath as text
end tell

We plan to add more volumes in the coming months years so there’s room for that in there. This is the paste path script which opens up a new window:


-- Set thePath to the clipboard's text
set thePath to the clipboard as text

-- Convert the "/" to ":"
set AppleScript's text item delimiters to ("\\" & "\\")
set thePathItems to text items of thePath
set AppleScript's text item delimiters to "\\"
set thePath to thePathItems as text
set AppleScript's text item delimiters to ""

-- Convert the "/" to ":"
set AppleScript's text item delimiters to "\\"
set thePathItems to text items of thePath
set AppleScript's text item delimiters to ":"
set thePath to thePathItems as text
set AppleScript's text item delimiters to ""

-- Convert the "/" to ":"
set AppleScript's text item delimiters to "/"
set thePathItems to text items of thePath
set AppleScript's text item delimiters to ":"
set thePath to thePathItems as text
set AppleScript's text item delimiters to ""

-- Set flag if it is a folder and eliminate trailing slash
if character (length of thePath) of thePath = ":" then
	set isFolder to "true"
	set theRevisedPath to characters 1 through ((length of thePath) - 1) of thePath
	set thePath to theRevisedPath as string
else
	set isFolder to "false"
end if

-- Convert buzzsaw server name to "Volumes"
set AppleScript's text item delimiters to "buzzsaw"
set thePathItems to text items of thePath
set AppleScript's text item delimiters to "Volumes"
set thePath to thePathItems as text
set AppleScript's text item delimiters to ""

-- Convert Buzzsaw server name to "Volumes"
set AppleScript's text item delimiters to "Buzzsaw"
set thePathItems to text items of thePath
set AppleScript's text item delimiters to "Volumes"
set thePath to thePathItems as text
set AppleScript's text item delimiters to ""

-- Convert network paths and set flags
set newPath to thePath
set AppleScript's text item delimiters to ":"
set theNewPathItems to text items of newPath
if text item 2 of theNewPathItems = "Volumes" then
	set AppleScript's text item delimiters to ":Volumes"
	set finalPathItems to text items of newPath
	set finalPath to text item 2 of finalPathItems as string
	set isNetworkPath to "true"
	set thePath to finalPath
else
	set isNetworkPath to "false"
end if

goToPath(thePath, isNetworkPath, isFolder)

on goToPath(thePath, isNetworkPath, isFolder)
	if isNetworkPath = "true" then
		if isFolder = "true" then
			openNetworkFolder(thePath)
		else
			openNetworkFileFolder(thePath)
		end if
	else
		if isFolder = "true" then
			openLocalFolder(thePath)
		else
			openLocalFileFolder(thePath)
		end if
	end if
end goToPath

on openLocalFolder(thePath)
	try
		tell application "Finder"
			set diskName to (name of startup disk)
			open folder (diskName & thePath)
		end tell
	on error
		openLocalFileFolder(thePath)
	end try
end openLocalFolder

on openLocalFileFolder(thePath)
	try
		tell application "Finder"
			set diskName to (name of startup disk)
			set AppleScript's text item delimiters to ":"
			set reversedPathTextItems to reverse of text items of thePath
			set filename to text item 1 of reversedPathTextItems
			set AppleScript's text item delimiters to filename
			set withFilenameTextItems to text items of thePath
			set theFinalPath to text item 1 of withFilenameTextItems
			open folder (diskName & theFinalPath)
		end tell
	on error
		openNetworkFolder(":Volumes:buzzsaw:WoodShop_Projects" & thePath)
	end try
	
end openLocalFileFolder

on openNetworkFolder(thePath)
	try
		tell application "Finder"
			open folder thePath
		end tell
	on error
		openNetworkFileFolder(thePath)
	end try
end openNetworkFolder

on openNetworkFileFolder(thePath)
	tell application "Finder"
		set AppleScript's text item delimiters to ":"
		set reversedPathTextItems to reverse of text items of thePath
		set filename to text item 1 of reversedPathTextItems
		set AppleScript's text item delimiters to filename
		set withFilenameTextItems to text items of thePath
		set thePath to text item 1 of withFilenameTextItems
		open folder thePath
	end tell
end openNetworkFileFolder

Hi. Welcome to MacScripter.

One obvious point about the first script is that workPath is set to a four-character text, so it will never equal “buzzsaw”.

Thanks Nigel. Switched the value to 6 to accomodate the characters.

  1. :wink:

I’ve also just noticed that ‘selectedPathItems’ is already a list of text items, so you should be extracting the ‘workPath’ value from ‘item 3 of selectedPathItems’, not from ‘text item 3 of selectedPathItems’. ‘Text items’ are delimited elements of text, not of lists.

Since you don’t use the ‘workPath’ variable again, it may be easier to replace those two lines with:

if (item 3 of selectedPathItems begins with "buzzsaw") then

Replaced and now get a variable message regarding PathItems, looking into how to define that.

Thanks for your help thus far. This is where we’re at:


tell application "Finder"
	set selectedPath to (POSIX path of (the selection as alias))
	set thePath to selectedPath
	set AppleScript's text item delimiters to "/"
	if (item 3 of selectedPathItems begins with "buzzsaw") then
		set workPath to (text 1 thru 7 of text item 3 of selectedPathItems) as string
		if workPath = "buzzsaw" then
			set AppleScript's text item delimiters to "Volumes"
			set thePathItems to text items of selectedPath
			set AppleScript's text item delimiters to "buzzsaw"
			set thePath to thePathItems as text
			set AppleScript's text item delimiters to "/"
			set thePathItems to text items of thePath
			set (text item 3 of thePathItems) to "WoodShop_Projects"
			set thePath to text items of thePathItems as string
			set AppleScript's text item delimiters to ""
		end if
	end if
	set AppleScript's text item delimiters to "/"
	set thePathItems to text items of thePath
	set AppleScript's text item delimiters to "\\"
	set thePath to thePathItems as text
	set AppleScript's text item delimiters to ""
	set selectedPath to ("\\" & thePath)
	set the clipboard to the selectedPath as text
end tell

Sorry. I didn’t notice that you’d misused ‘text item’ in the first ‘if’ line too, so it wasn’t clear which two lines my suggestion was supposed to replace. I meant:


	set AppleScript's text item delimiters to "/"
	set selectedPathItems to text items of selectedPath
	if (item 2 of selectedPathItems = "Volumes") then -- Or: if (text item 2 of selectedPath = "Volumes") then
		if (item 3 of selectedPathItems begins with "buzzsaw") then -- Or: if (text item 3 of selectedPath begins with "buzzsaw") then
			set AppleScript's text item delimiters to "Volumes"

In fact, this could be further reduced to:


	if (selectedPath begins with "/Volumes/buzzsaw") then
		set AppleScript's text item delimiters to "Volumes"

If I’ve correctly understood the purpose of the script, the same effect can be achieved with less editorial fuss like this:


tell application "Finder"
	set theSelection to selection
	-- Check that only one item is selected.
	if ((count theSelection) is 1) then
		set selectedPath to (POSIX path of (theSelection as alias))
	else
		activate
		display dialog "Please select one item (only)." buttons {"OK"} default button 1 with icon stop cancel button 1
	end if
end tell

-- Edit the path and place the result on the clipboard.
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "/"
set thePathItems to text items of selectedPath
if (selectedPath begins with "/Volumes/buzzsaw") then
	set item 2 of thePathItems to "buzzsaw"
	set item 3 of thePathItems to "WoodShop_Projects"
end if
set AppleScript's text item delimiters to "\\"
set thePath to thePathItems as text
set AppleScript's text item delimiters to astid

set the clipboard to ("\\" & thePath)

I’ll have a look at your other scripts later on.

Indeed you have, spot on Nigel. Thank you so much for your help thus far. Let me know when you’ve had a chance to take a look at the second part of the script, I’m sure there are more redundancies in that one as well.

Cheers,
Ben

Well. I’ve looked at the second script on and off during the day and have produced the version below. Within the confines of my two computers, and run from just one of them, it does the same as your original; but since I don’t understand why the path is sent to the clipboard in that format, I not sure if it’s what you want. Anyway, try it for yourself.

Warning: I’ve used just one handler to open whatever’s at or near the end of the path. I didn’t understand the purpose of trying other handlers in the event of errors, and have temporarily left in one of the ‘on error’ calls. The call’s effected recursively, so if it errors too, it’ll probably go into an infinite loop or something equally nasty.


-- Set thePath to the clipboard's text
set thePath to (the clipboard)

-- Convert the "\\\\" to "\\"
set thePath to findNreplace("\\\\", "\\", thePath)

-- Convert the "\\" to ":"
set thePath to findNreplace("\\", ":", thePath)

-- Convert the "/" to ":"
set thePath to findNreplace("/", ":", thePath)

-- Convert buzzsaw or Buzzsaw server name to "Volumes"
set thePath to findNreplace("buzzsaw", "Volumes", thePath)

-- Convert network paths and set flags
set isNetworkPath to (thePath begins with ":Volumes:")
if (isNetworkPath) then set thePath to text 9 thru -1 of thePath

openFolder(thePath, isNetworkPath)

on openFolder(thePath, isNetworkPath)
	-- If the path ends with ":" (assumed to be a folder or a disk rather than a bundle), this will open the end item;
	-- otherwise it'll open the container of the end item.
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to ":"
	-- Lose the leading colon and everything from and after the last colon in the path.
	set theFinalPath to text 2 thru text item -2 of thePath
	set AppleScript's text item delimiters to astid
	
	try
		if (isNetworkPath) then
			tell application "Finder" to open folder theFinalPath
		else
			tell application "Finder" to open folder theFinalPath of startup disk
		end if
	on error
		openFolder(":buzzsaw:WoodShop_Projects" & thePath, true)
	end try
end openFolder

on findNreplace(findStr, replaceStr, txt)
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to findStr
	set txt to txt's text items
	set AppleScript's text item delimiters to replaceStr
	set txt to txt as text
	set AppleScript's text item delimiters to astid
	
	return txt
end findNreplace

Just gave it a try, getting a stack overflow when called. Recursive / handler? Should I drop that one?

The reason we had so many was the various network volumes we had mapped to each stations startup procedure. So there was a projects directory, another share for FTP, another for Resources etc…

Ben

Undoubtedly. If the folder path derived from the original input doesn’t work in its own right, and that derived from (“:buzzsaw:Woodshop_Projects” & the original path) doesn’t work either, the handler will just keep calling itself and erroring until there’s no stack space left for return addresses, local variable values, the increasingly long path parameter, etc. It can be prevented by only doing the recursion if the path doesn’t already begin with “:buzzsaw:WoodShop_Projects”:

on openFolder(thePath, isNetworkPath)
	-- If the path ends with ":" (assumed folder or disk rather than bundle), this will open the end item;
	-- otherwise it'll open the container of the end item.
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to ":"
	set theFinalPath to text 2 thru text item -2 of thePath
	set AppleScript's text item delimiters to astid
	
	try
		if (isNetworkPath) then
			tell application "Finder" to open folder theFinalPath
		else
			tell application "Finder" to open folder theFinalPath of startup disk
		end if
	on error
		if (thePath begins with ":buzzsaw:WoodShop_Projects") then
			display dialog "invalid path \"" & thePath & "\"." buttons {"OK"} default button 1 cancel button 1 with icon stop
		else
			openFolder(":buzzsaw:WoodShop_Projects" & thePath, true)
		end if
	end try
end openFolder

But you’ll have to excuse my ignorance. All I’ve been doing so far is simplify your code. While I’m quite good at AppleScript, I’ve no experience of working with servers except for connecting to my other computer and am struggling to understand the need for the complexity. Why is the path stored on the clipboard? Is it for immediate or later use? Why isn’t it simply stored in HFS format? Is it to be used on the computer which obtained it or is it to be passed around?

Not to butt in but I too am confused as to how this is being used. It looks like killing a fly with a howitzer from the little I understand of it’s intended use.

Can you describe what’s happening better? You either have a really bad workflow (no offense, it happens) or an overly complicated script. Too many delimiters flying around! :stuck_out_tongue:

Jim

Apologies guys, had some troubles this morning we had to work through. On a deadline and now that has passed, onto the fun stuff -

First, Jim - admittedly! But we’re working on it. Let me see if I can clear some of this up and get us closer to an easily editable script that we can add to the mac scripter library.

The reason this gets copied into clipboard and partially why these scripts were so complex and had so many delimiters and “ifs” assigned to them is that at any given time I, and artists, will have 3 - 7 different share points and servers mounted to our systems. Here’s a screen grab of a few of the mounted points: http://i.imgur.com/GGvyD.png This was meant to be somewhat dynamic in that, tif someone was trying to send a path to a file on buzzsaw or FTP or IT, the script could accomodate your request for that file path and copy it to the clip board.

There are anywhere from 10 - 30 computers in the shop at any given time that are actively connected to our various work servers and working directly off of them. We use this script to send file paths of various assets artists or producers need for their work via iChat / AIM. Once the path was sent, the recipient could copy that path to their clipboard and as soon as it was copied, use the second script to regenerate a new finder window with the file they were being linked in that new finder window. So the howitzer analogy is apt, but in production we prefer howitzers. Especially if they are overkill, makes everyone feel better.

The other reason for the complicated script is that when we wrote this, the producers in the company were all on Macs while anyone creating content was on a PC. When a Mac handles a connected device it adds “volumes” to the beginning of the path. This, as you saw, was a problem since PC’s don’t interact with connected devices in the same manner. All one needed to do on the PC side was to copy the path from their AIM window and paste the path into their finder window and that was that. If a PC user was sending a path to a Mac user we needed the script to reincorporate that “Volumes” into the path before the path itself and that was added in the second script as you saw.

Let me know if this clarifies or further confuses things, I’ll be around for the rest of the day.

Cheers,
Ben

If the original POSIX path is “/Volumes/Buzzsaw/blah/blah/blah/”, your first script puts “\\Buzzsaw\WoodShop_Projects\blah\blah\blah\” on the clipboard. Your second script reconstitutes this as “:Volumes:WoodShop_Projects:blah:blah:blah” ” that is, “Buzzsaw” in the original becomes “WoodShop_Projects” in the reconstitution. Is this what you want?

Reconstitution ideally reads

\buzzsaw\DIRECTORY\blah\blah\blah\maya.mb

There are currently six subdirectories within buzzsaw, WoodShop_Projects would be the most used subdirectory for this script. Those are:

Isilon_Support
Dumping_Ground
WoodShop_Resources
WoodShop_Internal
WoodShop_Finals
WoodShop_Projects

Well it’s hard work, but the clues are trickling in and the picture’s slowly becoming less incoherent.

  1. A selected object may be either on one of several servers or on the user’s own machine. (The original scripts allow for either.)
  2. If on a server, the share point (ie. the path root) may be something called “Buzzsaw” or any of a number of subdirectories (mostly “WoodShop_Projects”) or something else entirely.
  3. If on a server, to humour PC users at your old job, the leading “/Volumes” must be omitted from the encoded path sent to the clipboard. (Presently, this only happens when the share point is “Buzzsaw”. As noted in my previous post, the name “WoodShop_Projects” is then inserted between “Buzzsaw” and the rest of the path, which is surely wrong. Encoded paths beginning with “\\Buzzsaw” are reconstituted as POSIX paths not containing “/Buzzsaw”, with the effect that “WoodShop_Projects” is substituted for “Buzzsaw” in any path based on the latter.)
  4. With no “/Volumes” in the reconstituted POSIX path, the second script must decide whether the path represents a local object or one on the network.
  5. If the path represents a folder, the second script should open the folder. If the path represents a file, the script should open the folder containing that file. (There’s currently no provision for bundles, whose paths also end with slashes or colons.)

How am I doing?

OK. Here’s another couple of tentative offerings. The first script puts a path on the clipboard in DOS network format. A local POSIX path can be turned into a network one simply by bopping “/Volumes/” & the volume name on the front, so the volume name is included for local paths. (I haven’t tried to make paths to local disks network-compatible, but they’ll work on the original computer.)

(* Place a DOS network-format path to a selected file or folder on the clipboard. *)

on main()
	tell application "Finder"
		set theSelection to selection
		
		-- Check that only one item is selected.
		if ((count theSelection) is 1) then
			set selectedPath to (POSIX path of (theSelection as alias))
			-- If it's a local path, prepend "/" and the local volume name.
			if (selectedPath begins with "/Users/") then set selectedPath to "/" & (name of startup disk) & selectedPath
		else
			activate
			display dialog "Please select one item (only)." buttons {"OK"} default button 1 with icon stop cancel button 1
		end if
	end tell
	
	-- Convert the path to DOS/Windows network format and place the result on the clipboard.
	-- Format: Two backslashes, server name, backslash separators. Here, "server name" could mean "sharepoint name" or "local volume name".
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "/"
	set thePathItems to text items of selectedPath
	if (item 2 of thePathItems is "Volumes") then
		-- If it's a network path, replace "Volumes" in the list with an empty text. This will also cause an additional instance of the "\\" delimiter in the coercion to text below.
		set item 2 of thePathItems to ""
	else
		-- Otherwise insert an empty text at the beginning of the list for the same effect.
		set beginning of thePathItems to ""
	end if
	set AppleScript's text item delimiters to "\\"
	set DOSPath to thePathItems as text
	set AppleScript's text item delimiters to astid
	
	set the clipboard to DOSPath
end main

main()

The second script reconstitutes the POSIX path from the DOS one on the clipboard and attempts to open the folder at the end of the path. If the path doesn’t work on the machine running the script, variations are tried with or without “Buzzsaw” in them to see if it’s just a sharepoint difference.

(* Open a folder indicated by a DOS network path on the clipboard. *)

on main()
	set DOSPath to (the clipboard)
	
	-- Convert the DOS network path to a POSIX network path.
	-- If the path is to a file (other than a bundle), the file name is dropped in the process, leaving just a path to the containing folder.
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "\\"
	set pathItems to text items 2 thru -2 of DOSPath
	set AppleScript's text item delimiters to "/"
	set POSIXPath to "/Volumes" & pathItems & "/"
	set AppleScript's text item delimiters to astid
	
	-- Open the folder, if possible.
	try
		try -- Try deriving an alias from the path.
			set folderAlias to POSIXPath as POSIX file as alias
		on error number -1700
			-- The path as passed doesn't work on the current machine.
			if (POSIXPath begins with "/Volumes/Buzzsaw/") then
				-- If the path sharepoint is Buzzsaw, try omitting "Buzzsaw" in case the computer's connected directly to the relevant subfolder.
				set folderAlias to ("/Volumes" & text 17 thru -1 of POSIXPath) as POSIX file as alias
			else
				-- If the path sharepoint's not Buzzsaw, try making it so.
				set folderAlias to ("/Volumes/Buzzsaw" & text 9 thru -1 of POSIXPath) as POSIX file as alias
			end if
		end try
		
		tell application "Finder" to open folderAlias
	on error number -1700
		tell application (path to frontmost application as text) to display dialog "The path \"" & POSIXPath & "\" can't be realised for some reason." buttons {"OK"} default button 1 with icon stop
	end try
end main

main()

Nigel, that was it. If ok with you, I’m going to go ahead and post this over in the MacScripter Library sometime tomorrow.

Cheers and thank you,
Ben