Open For Access, Permission Issues

I am suffering over a few fundamental AppleScript items that I just can’t seem to grasp.

¢ open for access
¢ File vs. Alias

And the posts I read still don’t seem to help in this case?

I am trying to collect a list of InDesign links into a text file that resides on the desktop. I would normally be okay with deleting the text file as soon as the script runs. But I can’t do that because sometimes I will need to add subsequent links from other documents to that same text file.

The guts of my script seem to work, but for some reason I am getting this error:

SystemUIServer got an error: File permission error.

on this line of code

set WiP to open for access outputFile with write permission

Can somebody PLEASE tell me what I am doing wrong?

I really appreciate the help.

Thanks,
Jeff

global outputList

on RemoveDuplicates(theList)
	set outputList to {}
	repeat with i from 1 to length of theList
		--    We make testItem a single-item list to ensure
		--    that sublists of the inputList are properly
		--    looked for in the outputlist.
		set thisItem to item i of theList
		set testItem to {thisItem}
		if (outputList does not contain testItem) then
			set end of outputList to thisItem
		end if
	end repeat
	return outputList
end RemoveDuplicates


set theList to {}



tell application "Adobe InDesign CS2"
	activate
	tell document 1
		set theLink to every link
		repeat with i from 1 to count of theLink
			set oriDelims to text item delimiters of AppleScript --puts the current delimiters into a variable
			set theImageName to file path of item i of theLink --extract full name
			set text item delimiters of AppleScript to {":"} --uses the colon as the new delimiter
			set theImageName to last text item of theImageName
			set text item delimiters of AppleScript to oriDelims --resets the old delimiters
			set end of theList to theImageName
			--display dialog theImageName
		end repeat
	end tell
end tell

--display dialog theList as string

set secondList to RemoveDuplicates(theList)



--Make a folder if not there
try
	set destPath to (path to current user folder as text) & "Desktop:"
	set fileName to "Links"
	tell application "Finder"
		make new file at folder destPath with properties {name:fileName}
	end tell
end try
set outputFile to (path to current user folder as text) & "Desktop:Links"
try
	set WiP to open for access outputFile with write permission
end try




---then empties the file, just in case.
tell application "SystemUIServer"
	set userResponse to display dialog "Do you want to clear the contents of the Links file?" buttons {"Yes", "No"}
	if button returned of userResponse is "Yes" then
		set WiP to outputFile
		try
			close access WiP
		end try
		set WiP to open for access outputFile with write permission
		set eof WiP to 0
	end if
end tell

--and loops thru all list items and writes each in turn to the file.
repeat with w from 1 to count of outputList
	write item w of outputList & return & return to WiP starting at eof
end repeat
close access WiP

How about this way?

   tell application "Finder" to set WiP to open for access outputFile with write permission

Unfortunately that will yield the same permission error, only targetting the Finder instead of SystemUIServer:

Finder got an error: File permission error.

Hi Jeff,

I guess the problem is the SystemUIServer tell block.
read and write belong to Standard Additions and need no target application.

It’s not necessary to create a file with the Finder.
The write command creates a file automatically if it doesn’t exist.

Your open and close sequences look quite confusing.
I don’t understand this line

set WiP to outputFile

WiP is an internal pointer to the file, but outputFile is a string path.
This is a difference

If you read and write to the same file from several scripts, you should use one script to manage the accesses

I’d recommend to use always the syntax

file [string path]

PS:

a suggestion:


.
set secondList to RemoveDuplicates(theList)

set outputFile to ((path to desktop as text) & "Links.txt")
try
	set WiP to open for access file outputFile with write permission
	
	---then empties the file, just in case.
	set userResponse to display dialog "Do you want to clear the contents of the Links file?" buttons {"Yes", "No"}
	if button returned of userResponse is "Yes" then set eof WiP to 0
	
	--and loops thru all list items and writes each in turn to the file.
	set {TID, text item delimiters} to {text item delimiters, (return & return)}
	set outputList to outputList as text
	set text item delimiters to TID
	write outputList & return & return to WiP starting at eof
	close access WiP
on error
	try
		close access file outputFile
	end try
end try

I would also keep your open for access and close access in the same try block so that you can close access to the file with our on error if you run into an error. I forget the exact problems of not closing access to the file but much like resetting AppleScript’s text item delimiters I believe that it is a good practice to always close access to the file even (or especially?) if the scripts quits due to an error.

Hi Stefan and Jerome,
I owe you a great deal of thanks. And I apologize for taking so long to get back to you. I don’t script that often. So every time I get back into it, I forget lots of things. I learned so much from this tiny script, including the importance of text item delimiters. You were more helpful than you may realize.

Thanks,
Jeff

I am having difficulty with either the text item delimiters or the setting the eof to 0 aspect.

This script is working. But the final text document always yields the first line followed by 4 returns, whereas ever other line of text is followed by two returns (that is preferred) yet one would be better. I know the script is long and cumbersome, but maybe somebody can explain what I am missing? I really do appreciate any gesture of goodwill :slight_smile:

I realize I have a handler towards the bottom of the script that shouldn’t really be at that spot. For now it is helping me see things flow a bit.

Thanks,
Jeff

global outputList



on RemoveDuplicates(theList)
	set outputList to {}
	repeat with i from 1 to length of theList
		--    We make testItem a single-item list to ensure
		--    that sublists of the inputList are properly
		--    looked for in the outputlist.
		set thisItem to item i of theList
		set testItem to {thisItem}
		if (outputList does not contain testItem) then
			set end of outputList to thisItem
		end if
	end repeat
	return outputList
end RemoveDuplicates

on RemoveDuplicates2(theSecondList)
	set outputList2 to {}
	repeat with i from 1 to length of theSecondList
		--    We make testItem a single-item list to ensure
		--    that sublists of the inputList are properly
		--    looked for in the outputlist.
		set thisItem to item i of theSecondList
		set testItem to {thisItem}
		if (outputList2 does not contain testItem) then
			set end of outputList2 to thisItem
		end if
	end repeat
	return outputList2
end RemoveDuplicates2




set theList to {}
tell application "Adobe InDesign CS2"
	activate
	tell document 1
		set theLink to every link
		repeat with i from 1 to count of theLink
			set oriDelims to text item delimiters of AppleScript --puts the current delimiters into a variable
			set theImageName to file path of item i of theLink --extract full name
			set text item delimiters of AppleScript to {":"} --uses the colon as the new delimiter
			set theImageName to last text item of theImageName
			set text item delimiters of AppleScript to oriDelims --resets the old delimiters
			set end of theList to theImageName
			--display dialog theImageName
		end repeat
	end tell
end tell

--display dialog theList as string

set secondList to RemoveDuplicates(theList)

set outputFile to ((path to desktop as text) & "Links.txt")
try
	set WiP to open for access file outputFile with write permission
	
	---then empties the file, just in case.
	--make the dialog box the frontmost application
	tell application "SystemUIServer"
		set userResponse to display dialog "Do you want to clear the contents of the Links file?" buttons {"Yes", "No"}
	end tell
	if button returned of userResponse is "Yes" then set eof WiP to 0
	
	
	if button returned of userResponse is "No" then
		tell application "TextEdit"
			try
				open outputFile
				tell application "System Events"
					tell application process "TextEdit"
						set frontmost to true
						keystroke "a" using {command down}
					end tell
				end tell
				tell application "System Events"
					tell application process "TextEdit"
						set frontmost to true
						keystroke "c" using {command down}
					end tell
				end tell
				tell application "System Events"
					tell application process "TextEdit"
						set frontmost to true
						keystroke "w" using {command down}
					end tell
				end tell
			end try
		end tell
	end if
	
	--and loops thru all list items and writes each in turn to the file.
	set {TID, text item delimiters} to {text item delimiters, (return & return)}
	set outputList to outputList as text
	set text item delimiters to TID
	write outputList & return & return to WiP starting at eof
	--write outputList to WiP starting at eof
	close access WiP
on error
	try
		close access file outputFile
	end try
end try

set theSecondList to {}
--Change Text Item Delimiters
--set {TID, text item delimiters} to {text item delimiters, (return & return)}

tell application "TextEdit"
	open file outputFile
	set theLinkNames to every paragraph of document 1
	--display dialog theLinkNames as string
	repeat with i from 1 to (count of theLinkNames)
		set TID to text item delimiters of AppleScript --puts the current delimiters into a variable
		set theImageName2 to item i of theLinkNames
		set text item delimiters of AppleScript to {":"} --uses the colon as the new delimiter
		set theImageName2 to last text item of theImageName2
		set text item delimiters of AppleScript to TID --resets the old delimiters
		--set end of theList to theImageName
		set end of theSecondList to theImageName2
		--display dialog theImageName
	end repeat
end tell


tell application "System Events"
	tell application process "TextEdit"
		set frontmost to true
		keystroke "w" using {command down}
	end tell
end tell





(*///////////////////////////////
///////////////////////////////
///////////////////////////////
///////////////////////////////
///////////////////////////////
///////////////////////////////
/////////////////////////////// *)
on RemoveDuplicates3(theList)
	set outputList to {}
	repeat with i from 1 to length of theList
		--    We make testItem a single-item list to ensure
		--    that sublists of the inputList are properly
		--    looked for in the outputlist.
		set thisItem to item i of theList
		set testItem to {thisItem}
		if (outputList does not contain testItem) then
			set end of outputList to thisItem
		end if
	end repeat
	return outputList
end RemoveDuplicates3





set theNewFile to ((path to desktop as text) & "Links.txt")
try
	set WiP to open for access file theNewFile with write permission
	set theList to {}
	
	tell application "TextEdit"
		open file theNewFile
		set theLinkNames to every paragraph of document 1
		--display dialog theLinkNames as string
		repeat with i from 1 to (count of theLinkNames)
			set TID to text item delimiters of AppleScript --puts the current delimiters into a variable
			set theImageName2 to item i of theLinkNames
			set text item delimiters of AppleScript to {":"} --uses the colon as the new delimiter
			set theImageName2 to last text item of theImageName2
			set text item delimiters of AppleScript to TID --resets the old delimiters
			--set end of theList to theImageName
			set end of theList to theImageName2
			--display dialog theImageName
		end repeat
		close document 1
	end tell
	
	
	
	
	set theList to RemoveDuplicates3(theList)
	
	
	
	
	--and loops thru all list items and writes each in turn to the file.
	set {TID, text item delimiters} to {text item delimiters, (return & return)}
	set outputList to outputList as text
	set text item delimiters to TID
	set eof WiP to 0
	write outputList & return & return to WiP starting at eof
	--write outputList to WiP starting at eof
	close access WiP
on error
	try
		close access file theNewFile
	end try
end try

sorry, I don’t understand some parts of your script at all

¢ why do you strip the last text item after writing to the file the first time, you actually write just file names into the file, not paths!
¢ why do you put the contents of the text file to the clipboard, if the user presses NO?
¢ why do you use the code of a subroutine 3 times instead of calling the same subroutine with different parameters?

btw, TextEdit is not needed to put the contents of the file to the clipboard, replace


	if button returned of userResponse is "No" then
		tell application "TextEdit"
			try
				open outputFile
				tell application "System Events"
					tell application process "TextEdit"
						set frontmost to true
						keystroke "a" using {command down}
					end tell
				end tell
				tell application "System Events"
					tell application process "TextEdit"
						set frontmost to true
						keystroke "c" using {command down}
					end tell
				end tell
				tell application "System Events"
					tell application process "TextEdit"
						set frontmost to true
						keystroke "w" using {command down}
					end tell
				end tell
			end try
		end tell
	end if

with


if button returned of userResponse is "No" then
	set the clipboard to (read file outputFile)
end if

and to gather the file names of the links this is sufficient


tell application "Adobe InDesign CS3"
	tell document 1 to set theList to name of every link
end tell

Hello Stefan.
I really messed up and shouldn’t have included that clipboard aspect. I was going about this very wrong.

I tried to use what you gave me to rework this. I also tried to use one handler. (this is not easy for me) :frowning:

My test dialogs that I threw in their look like correct lists. But when the script writes to the text document, the lines of links (or words) are preceded by random unicode txt characters, usually beginning with txt

Any idea what may be causing this? Other than that I think the below script would work.

on RemoveDuplicates(theList)
	set outputList to {}
	repeat with i from 1 to length of theList
		--    We make testItem a single-item list to ensure
		--    that sublists of the inputList are properly
		--    looked for in the outputlist.
		set thisItem to item i of theList
		set testItem to {thisItem}
		if (outputList does not contain testItem) then
			set end of outputList to thisItem
		end if
	end repeat
	return outputList
end RemoveDuplicates



--This will get a list of links from InDesign
tell application "Adobe InDesign CS2"
	activate
	tell document 1 to set theList to name of every link as list
end tell



display dialog theList as string


--We must write the list to a text document on the desktop separated by returns

set outputFile to ((path to desktop as text) & "Links.txt")
try
	set WiP to open for access file outputFile with write permission
	---then empties the file, just in case.
	--make the dialog box the frontmost application
	tell application "SystemUIServer"
		set userResponse to display dialog "Do you want to clear the contents of the Links file?" buttons {"Yes", "No"}
	end tell
	--In case a list was on the document and we didn't need it, we would clear the text document.
	if button returned of userResponse is "Yes" then set eof WiP to 0
	--Otherwise we would want to add the new list to the existing list already on the document.
	set TID to text item delimiters of AppleScript --puts the current delimiters into a variable
	set text item delimiters of AppleScript to {(return & return)} --uses the colon as the new delimiter
	set theList to theList as text
	--set delimiters back to old
	set text item delimiters of AppleScript to TID
	write theList to WiP starting at eof
	close access WiP
on error
	try
		close access file outputFile
	end try
end try



--Now we need to get the paragraphs of the document

set theParagraphList to {}
tell application "TextEdit"
	open file outputFile
	set eachParagraph to every paragraph of document 1
	repeat with i from 1 to (count of eachParagraph)
		set eachParagraphName to item i of eachParagraph
		set eachParagraphName to last text item of eachParagraphName
		set end of theParagraphList to eachParagraphName
	end repeat
end tell
display dialog theParagraphList as string

--sets theParagraphs list to theList so the initial handler can get rid of the duplicates

set theList to theParagraphList


set secondList to RemoveDuplicates(theList)


--This will write the new non-duplicate paragraph list to the text doucument.

try
	set WiP to open for access file outputFile with write permission
	set eof WiP to 0
	write secondList to WiP starting at eof
	close access WiP
on error
	try
		close access file outputFile
	end try
end try

Sorry, Jeff, I’m lost.
The TextEdit part is confusing because if no text item delimiters are specified,
so the default value {“”} will result only a list of carriage returns

Hi Stefan,
Your last response helped me more than you may realize. Setting the text delimiters helped. Yet I still need to do some serious learning.

I was also forgetting to set my list to “text” before writing it to the text document. That seemed to get rid of the extra text characters. I also realized I could and a return to my list by simply writing this:

write theList & return to WiP starting at eof

It’s those little things that I pull my hair out with.

This script is working very well. I still have the top line of my text file’s list followed by a few extra returns. But I can write a script to replace those 4 returns with 2 return.

Many thanks again for all of your help.

-Jeff

on RemoveDuplicates(theList)
	
	
	set outputList to {}
	repeat with i from 1 to length of theList
		set TID to text item delimiters of AppleScript --puts the current delimiters into a variable
		--    We make testItem a single-item list to ensure
		--    that sublists of the inputList are properly
		--    looked for in the outputlist.
		set thisItem to item i of theList
		set text item delimiters of AppleScript to {(return)} --uses the return as the new delimiter
		set testItem to {thisItem}
		if (outputList does not contain testItem) then
			set end of outputList to thisItem
		end if
	end repeat
	return outputList
	set text item delimiters of AppleScript to TID --resets the old delimiters
end RemoveDuplicates



--This will get a list of links from InDesign
tell application "Adobe InDesign CS2"
	activate
	tell document 1 to set theList to name of every link as list
end tell



display dialog theList as string


--We must write the list to a text document on the desktop separated by returns

set outputFile to ((path to desktop as text) & "Links.txt")


try
	set WiP to open for access file outputFile with write permission
	---then empties the file, just in case.
	--make the dialog box the frontmost application
	tell application "SystemUIServer"
		set userResponse to display dialog "Do you want to clear the contents of the Links file?" buttons {"Yes", "No"}
	end tell
	--In case a list was on the document and we didn't need it, we would clear the text document.
	if button returned of userResponse is "Yes" then set eof WiP to 0
	--Otherwise we would want to add the new list to the existing list already on the document.
	set TID to text item delimiters of AppleScript --puts the current delimiters into a variable
	set text item delimiters of AppleScript to {(return & return)} --uses the return as the new delimiter
	set theList to theList as text
	--set delimiters back to old
	set text item delimiters of AppleScript to TID
	write theList & return to WiP starting at eof
	close access WiP
on error
	try
		close access file outputFile
	end try
end try



--Now we need to get the paragraphs of the document

try
	set theParagraphList to {}
	tell application "TextEdit"
		open file outputFile
		set eachParagraph to every paragraph of document 1
		repeat with i from 1 to (count of eachParagraph)
			set TID to text item delimiters of AppleScript --puts the current delimiters into a variable
			set eachParagraphName to item i of eachParagraph
			set text item delimiters of AppleScript to {":"} --uses the colon as the new delimiter
			set eachParagraphName to last text item of eachParagraphName
			set text item delimiters of AppleScript to TID --resets the old delimiters
			set end of theParagraphList to eachParagraphName
		end repeat
		close document 1
	end tell
	display dialog theParagraphList as string
	
	
	--sets theParagraphs list to theList so the initial handler can get rid of the duplicates
	
	set theList to theParagraphList
	
	set secondList to RemoveDuplicates(theList)
end try

--This will write the new non-duplicate paragraph list to the text doucument.
try
	set WiP to open for access file outputFile with write permission
	set {TID, text item delimiters} to {text item delimiters, (return & return)}
	set secondList to secondList as text
	set text item delimiters to TID
	set eof WiP to 0
	write secondList to WiP starting at eof
	close access WiP
on error
	try
		close access file outputFile
	end try
end try