I'm pretty new to applescript and I can't get past the point of accepting arguments from the command line. I've read that I can do it like this:
on run argv
log "SOMETHIG
end run
on readLines(unixPath)
set targetFile to (open for access (POSIX file unixPath))
set fileText to (read targetFile for (get eof targetFile) as text)
set fileLines to every paragraph of fileText
close access targetFile
return fileLines
end readLines
The problem is that it doesn't let me define on run argv together with other functions (or handlers) define with on while it lets me define any number of funciona (apart from on run argv). How come?
on run
log "Something"
end run
and
log "Something"
do the same thing. The first script has an explicit run handler while the second, an implicit run handler. A script object can only have one run handler.
This script would not work because you can't have a handler inside a handler
on run
log "SOMETHIG"
on readLines(unixPath)
set targetFile to (open for access (POSIX file unixPath))
set fileText to (read targetFile for (get eof targetFile) as text)
set fileLines to every paragraph of fileText
close access targetFile
return fileLines
end readLines
end run
However you can define a handler outside "on run" and call it from within:
on run
log "Something"
readLines("/Users/pistacchio/Desktop/test.txt")
end run
on readLines(unixPath)
set targetFile to (open for access (POSIX file unixPath))
set fileText to (read targetFile for (get eof targetFile) as text)
set fileLines to every paragraph of fileText
close access targetFile
return fileLines
end readLines
Alternatively, you can simply use the implicit run handler:
log "Something"
readLines("/Users/pistacchio/Desktop/test.txt")
on readLines(unixPath)
set targetFile to (open for access (POSIX file unixPath))
set fileText to (read targetFile for (get eof targetFile) as text)
set fileLines to every paragraph of fileText
close access targetFile
return fileLines
end readLines
Related
I would like to scan thru my Photo library (macOS 10.15.6, Photos App 5.0) and export selected photos' original file name to a text file. I have a simple script below as a starting point that doesn't properly convert the filename to readable text. I expect I need to execute some kind of 'convert to string' operation on the filename but I'm coming up empty on answers...
Any suggestions would be appreciated
code I'm currently using:
set myFile to open for access "/Users/ed/Desktop/testFile.txt" with write permission
write "file start\n" to myFile
tell application "Photos"
activate
set imageSel to (get selection)
if imageSel is {} then
error "Please select an image."
else
repeat with im in imageSel
write filename of im to myFile
write "\nnext photo\n" to myFile
end repeat
end if
end tell
write "file end\n" to myFile
close access myFile
My suggestion is to build the list of file names, then convert the list to paragraphs with text item delimiters and write the text to disk.
Further it's highly recommended to add reliable error handling to the write part.
tell application "Photos"
set imageSel to selection
if imageSel is {} then
error "Please select an image."
else
set theNames to {"file start"}
repeat with im in imageSel
set end of theNames to filename of im
end repeat
set end of theNames to "file end"
end if
end tell
set {TID, text item delimiters} to {text item delimiters, linefeed}
set theNames to theNames as text
set text item delimiters to TID
set testFile to POSIX path of (path to desktop) & "testFile.txt"
try
set fileDescriptor to open for access testFile with write permission
write theNames to fileDescriptor
close access fileDescriptor
on error
try
close testFile
end try
end try
I have a repeat which have
repeat with myrecordID in rtetr
set refpdf to field "File Attachments" of record myrecordID
if refpdf is "" then
set noref to noref + 1
else
set refpdf2 to POSIX path of (docs & "/PDF" & refpdf1)
set thePath to refpdf2
set thePath1 to my convertPathToAlias(thePath)
set thePath1 to thePath1 as text
end if
end repeat
variable is path to some files
I want to write this variable to a text file & add each path to a line.
but when I try
set myFile to open for access addtemp with write permission
write namesText to myFile
close access myFile
It only write the last variable, not all of them from repeat.
I also tried this
try
set fileDescriptor to open for access addtemp with write permission
write thePath1 & return to fileDescriptor
close access fileDescriptor
on error e number n
try
close access file addtemp
end try
display dialog "Error: " & e & " - number: " & n buttons {"Cancel"} default button "Cancel"
end try
but no chance
Ok it seems you are working with in a tell block for some application you haven't mentioned — set refpdf to field "File Attachments" of record myrecordID is not standard AppleScript, and won't compile on its own — but using a generic application name, I think you want something that looks like this (please remember to replace "Generic Name" with the name of the app in question):
try
set myFile to open for access addtemp with write permission
on error
close access addtemp
set myFile to open for access addtemp with write permission
end try
tell application "Generic Name"
repeat with myrecordID in rtetr
set refpdf to field "File Attachments" of record myrecordID
if refpdf is "" then
set noref to noref + 1
-- write out a notice that there was no data, with a line break after
write "No Reference" & return to myFile
else
set refpdf2 to POSIX path of (docs & "/PDF" & refpdf1)
set thePath to refpdf2
set thePath1 to my convertPathToAlias(thePath)
set thePath1 to thePath1 as text
-- write out the data, with a line break after
write thePath1 & return to myFile
end if
end repeat
end tell
close access myFile
In short, you open the write-out file at the start of the script, write the data sequentially inside the repeat loop, and then close the file at the end.
The try block at the beginning handles a frequent problem: if your script errors out before the close statement, the file handle is left open and can error if you try to open it again; this try block detects an error, and tries to close and reopen the file handle.
You may need to put the keyword my before the write statements if the app in question defines its own write command.
There is a method to write data in the file:
to output:someThing toFile:someFile
try
tell application "System Events" to set myname to get name of (path to me)
set AppleScript's text item delimiters to myname
set pathToFolder to text item 1 of ((path to me) as text)
set outputFileWithPath to (((pathToFolder) as text) & someFile)
set fileRef to (open for access outputFileWithPath with write permission)
write (someThing) to fileRef starting at 0
close access fileRef
on error errmess
log errmess
try -- make sure file is closed on any error
close access fileRef
end try
end try
end output:toFile:
set outputFile to "test1"
(my output:"first second third" toFile:outputFile)
(my output:"forth" toFile:outputFile)
The issue in this example is: in the end, I will have a file with:
forth second third
The goal is to have only last record. In this example:
forth
The write (someThing) to fileRef starting at [...] construction is meant to insert new data into a file: it overwrites data at that point in the file without changing anything else. If you want to delete the contents of the file after some certain point, use set eof fileRef to [some integer]. 'eof' here stands for 'end of file'. Your code would be:
set fileRef to (open for access outputFileWithPath with write permission)
set eof fileRef to 0
write (someThing) to fileRef
close access fileRef
I am attempting to read the contents of a txt file (list of IP addresses) and then make a list from them to use in a shell script loop. Seems to error on the "set Switches to paragraphs of (read POSIX file file path)" and I assume I need to reconstruct but I know Applescript and barely getting into ObjC so this one has me stumped....
I really want to change the first three lines to set filepath to choose file but I get the same error.
on theButtonChooseFile_(sender)
set x to (system info)
set theuser to short user name of x
set filepath to "/Users/" & theuser & "/Desktop/switches.txt" as string -- Define path to file
set listOfSwitches to {}
set Switches to paragraphs of (read POSIX file filepath)
repeat with nextLine in Switches
if length of nextLine is greater than 0 then
copy nextLine to the end of listOfSwitches
end if
end repeat
end theButtonChooseFile_
Error:
2016-08-25 08:13:37.655 Cisco Configurator[67884:4593159] *** -[AppDelegate theButtonChooseFile:]: Can’t make current application into type file. (error -1700)
The AppleScript read command accepts also POSIX paths and you can get the path to the desktop folder of the current user simply with
path to desktop
The entire handler can be written this way
on theButtonChooseFile_(sender)
set desktopFolder to POSIX path of (path to desktop)
set filepath to desktopFolder & "switches.txt"
set Switches to paragraphs of (read filepath)
set listOfSwitches to {}
repeat with nextLine in Switches
if length of nextLine is greater than 0 then
copy nextLine to the end of listOfSwitches
end if
end repeat
end theButtonChooseFile_
But consider than listOfSwitches is only accessible in the handler.
I am trying to write a simple logger with Applescript. I have a couple of questions
Firstly I am testing if a file exists, if it does not I want to create a file with that name and set the first line to a string "Counter:0".
So far I have this but my syntax is wrong. Appreciate any help as the info on the web is a bit slender.
tell application "Finder"
set thePath to "/Data/GameLog/"
set theFile to thePath & (do shell script "date '+%Y.%m.%d'" & ".log")
if exists POSIX file thePath then
--display dialog "Found"
else
do shell script "Counter:0" > echo thePath
end if
end tell
secondly I would like to read the first line of the file (ie Counter:0) and increment the integer after the : by 1.
Help v.much appreciated
Based on vadian's answer:
set logFolder to (POSIX path of (path to home folder)) & "Desktop/" -- the trailing slash is crucial
set timeStamp to do shell script "date '+%Y.%m.%d'"
set logFile to logFolder & timeStamp & ".log"
if ((do shell script "test -d " & quoted form of logFolder & "&& echo true||echo false") as boolean) then
try
close access logFile
end try
try
set fileReference to open for access logFile with write permission
on error
display alert "File already open"
return -1
end try
set counter to (get eof of fileReference)
if counter is not 0 then
try
set counter to (read fileReference from 9) as integer
on error
close access logFile
display alert "Read error"
return -1
end try
set counter to counter + 1
set eof of fileReference to 0
end if
write ("Counter:" & counter) to fileReference as «class utf8»
close access logFile
else
display alert "Folder does not exist"
end if
The advantage is that this will not ignore errors. It will also be able to find your home directory without needing you to manually enter it in code. This is safe since we check for the logFolder first. The rest of the code can't fail if that folder exists. I am aware that AppleScript has a method for checking whether or not a file exists, but I have found that functionality to be fairly difficult to use when dealing with POSIX paths, so I'm using a do shell script instead, which naturally deals with POSIX paths.
Please try this, change the file path in the first line (consider the trailing slash)
set logFolder to "/Users/myUser/Desktop/" -- the trailing slash is crucial
set timeStamp to do shell script "date '+%Y.%m.%d'"
set logFile to logFolder & timeStamp & ".log"
try
set fileReference to open for access logFile with write permission
set counter to (get eof of fileReference)
if counter is not 0 then
set counter to read fileReference from 9
set counter to counter + 1
set eof of fileReference to 0
end if
write ("Counter:" & counter) to fileReference as «class utf8»
close access fileReference
on error
try
close access logFile
end try
end try