I wanted to make a small app in applescript that polled the clipboard for changes and upon detecting any, dumped the contents of the clipboard into a text file. here is the code i came up with, it creates the file but nothing gets written into it. what am i doing wrong?
property oldvalue : missing value
on idle
local newValue
set newValue to the clipboard
if oldvalue is not equal to newValue then
try
tell application "Finder"
try
set the_file to "/Users/xxx/Documents/dump2.txt" as POSIX file as alias
on error
set the_file to (make new document file at ("/Users/xxx/Documents/" as POSIX file as alias) with properties {name:"dump2", text:""})
end try
end tell
try
open for access the_file with write permission
write newValue to file the_file starting at eof
close access the_file
on error
try
close access the_file
end try
end try
end try
set oldvalue to newValue
end if
return 1
end idle
open for access also accepts a POSIX path as text as an argument, and the path specified as an argument does not have to exist. Your script didn't work because make new document file returns a Finder file object, and the as POSIX file as alias part always resulted in an error.
property old : ""
on idle
set new to the clipboard
if new is not old then
set old to new
if new does not end with linefeed then set new to new & linefeed
set b to open for access "/tmp/clipboard.txt" with write permission
write new to b as «class utf8» starting at eof
close access b
end if
return 1
end idle
as «class utf8» is needed because write still uses the primary encoding (like MacRoman or MacJapanese) by default. as Unicode text would be UTF-16.
Related
I was looking for a script that would batch convert all *.numbers files in a given folder to *.csv files.
I found the following on GitHub and added an additional line as suggested in the comments suggestion. When I run the script, Numbers launches and opens the test file from the folder specified - but the file is not exported. Numbers just stays open and terminal errors out with:
/Users/Shared/Untitled.scpt: execution error: Numbers got an error: Invalid key form. (-10002)
The script (located in /Users/Shared) has the following permissions:
-rwxr-xr-x
#!/usr/bin/osascript
on run argv
set theFilePath to POSIX file (item 1 of argv)
set theFolder to theFilePath as alias
tell application "Finder" to set theDocs to theFolder's items
-- Avoid export privilege problem
set privilegeFile to (theFolder as text) & ".permission"
close access (open for access privilegeFile)
repeat with aDoc in theDocs
set docName to aDoc's name as text
if docName ends with ".numbers" then
set exportName to (theFolder as text) & docName
set exportName to exportName's text 1 thru -9
set exportName to (exportName & "csv")
tell application "Numbers"
open aDoc
delay 5 -- may need to adjust this higher
tell front document
export to file exportName as CSV
close
end tell
end tell
end if
end repeat
end run
Any suggestions?
Here is what I did and works for me in macOS High Sierra:
In Terminal:
touch numb2csv; open -e numb2csv; chmod +x numb2csv
• This creates an empty ASCII Text file named numb2csv.
• Opens, by default, numb2csv in TextEdit.
• Makes the numb2csv file executable.
Copy and paste the example AppleScript code, shown further below, into the opened numb2csv file.
Save and close the numb2csv file.
In Terminal executed the numb2csv executable file, e.g.:
./numb2csv "$HOME/Documents"
This created a CSV file of the same name as each Numbers document in my Documents folder, not traversing any nested folders.
Example AppleScript code:
#!/usr/bin/osascript
on run argv
set theFilePath to POSIX file (item 1 of argv)
set theFolder to theFilePath as alias
tell application "System Events" to set theDocs to theFolder's items whose name extension = "numbers"
repeat with aDoc in theDocs
set docName to aDoc's name as text
set exportName to (theFolder as text) & docName
set exportName to exportName's text 1 thru -8
set exportName to (exportName & "csv")
tell application "Numbers"
launch
open aDoc
repeat until exists document 1
delay 3
end repeat
tell front document
export to file exportName as CSV
close
end tell
end tell
end repeat
tell application "Numbers" to quit
end run
NOTE: As coded, this will overwrite an existing CSV file of the same name as each Numbers file processed, if they already exist. Additional coding required if wanting to not overwrite existing files
If you receive the Script Error:
Numbers got an error: The document “name” could not be exported as “name”. You don’t have permission.
It is my experience that the Numbers document was not fully opened prior to being exported and that increasing the value of the delay command resolves this issue. This is of course assuming that one actually has write permissions in the folder the target Numbers documents exists.
Or one can introduce an error handler within the tell front document block which, if my theory is right about the target document not being fully loaded before the export, will give additional time, e.g.:
Change:
tell front document
export to file exportName as CSV
close
end tell
To:
tell front document
try
export to file exportName as CSV
close
on error
delay 3
export to file exportName as CSV
close
end try
end tell
Note: The primary example AppleScript code is just that and does not contain any error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. See included example directly above.
I was looking for that, unfortunately, that doesn’t work anymore.
This line
tell application "System Events" to set theDocs to theFolder's items whose name extension = "numbers"
Gets the following error:
execution error: Can’t make file "file.numbers" of application "System Events" into the expected type. (-1700)
macOs Big Sur Versio 11.01
automator version 2.10
Numbers version 10.3.5
Inspired by this thread and those articles Exporting Numbers Documents and Get full directory contents with AppleScript
The following code works:
#!/usr/bin/osascript
log "Start"
property exportFileExtension : "csv"
tell application "Finder"
activate
set sourceFolder to choose folder with prompt "Please select directory."
set fileList to name of every file of sourceFolder
end tell
set the defaultDestinationFolder to sourceFolder
repeat with documentName in fileList
log "documentName: " & documentName
set fullPath to (sourceFolder as text) & documentName
log "fullPath: " & fullPath
if documentName ends with ".numbers" then
set documentName to text 1 thru -9 of documentName
tell application "Finder"
set newExportItemName to documentName & "." & exportFileExtension
set incrementIndex to 1
repeat until not (exists document file newExportItemName of defaultDestinationFolder)
set newExportItemName to ¬
documentName & "-" & (incrementIndex as string) & "." & exportFileExtension
set incrementIndex to incrementIndex + 1
end repeat
end tell
set the targetFileHFSPath to ¬
(defaultDestinationFolder as string) & newExportItemName
tell application "Numbers"
launch
open fullPath
with timeout of 1200 seconds
export front document to file targetFileHFSPath as CSV
end timeout
close
end tell
end if
end repeat
user3439894's answer works with a few change:
exists document 1 => number of documents > 0
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'm trying to get a script working which is able to batch export .mts format video files via quicktime into .mov files in 1080p. The script fails with the following error: "The action “Run AppleScript” encountered an error: “QuickTime Player got an error: Can’t make file (document "00000.MTS") into type «class fsrf».”". I assume this has something to do with using text file paths? Note I'm not experienced with Applescript and would really appreciate any help to get this simple bit of script working. Currently it's in automator as a service:
on run {inputFiles}
if inputFiles is equal to {} then
set inputFiles to (choose file with prompt "Select the file(s) to convert:" with multiple selections allowed without invisibles)
end if
open inputFiles
end run
on open droppedItems
tell application "Finder" to set inputFolder to (container of first item of droppedItems) as Unicode text
set outputFolder to (choose folder with prompt "Select output folder:" default location (inputFolder as alias)) as Unicode text
set exportPreset to (choose from list {"Movie", "iPhone", "iPod", "480p", "720p", "1080p"} with prompt "Choose QuickTime Export Preset:") as Unicode text
if exportPreset is equal to "false" then
return
end if
repeat with currentItem in droppedItems
repeat until getProcessPercentCPU("CoreMediaAuthoringSessionHelper") is equal to ""
end repeat
tell application "Finder" to set fileName to name of currentItem as Unicode text
set fileName to text 1 thru ((fileName's length) - (offset of "." in ¬
(the reverse of every character of fileName) as text)) of fileName
convertFile(currentItem, outputFolder & fileName & ".mov", exportPreset)
end repeat
end open
on convertFile(inputFile, outputFile, exportPreset)
tell application "QuickTime Player"
set thisMovie to open inputFile
open for access file thisMovie
close access file thisMovie
export thisMovie in (outputFile) using settings preset exportPreset
close thisMovie
end tell
end convertFile
on getProcessPercentCPU(processName)
do shell script "/bin/ps -xco %cpu,command | /usr/bin/awk '/" & processName & "$/ {print $1}'"
end getProcessPercentCPU
Try changing:
set outputFolder to (choose folder with prompt "Select output folder:" default location (inputFolder as alias)) as Unicode text
to:
set outputFolder to POSIX path of (choose folder with prompt "Select output folder:" default location (inputFolder as alias))
and:
convertFile(currentItem, outputFolder & fileName & ".mov", exportPreset)
to:
set outputFile to POSIX file (outputFolder & fileName & ".mov")
convertFile(currentItem, outputFile, exportPreset)
and remove the open for access/close access commands.
Sandboxed apps don't like receiving path strings to open/save commands, but accept alias/POSIX file values okay. (If it still doesn't work then it's some other issue at play, but that's always the first thing to check when you get a filesystem permissions error as you describe.)
The error occurs because thisMovie is a document reference of QuickTime Player and this class cannot be converted / coerced to a file system reference («class fsrf»).
That's what the error message says
Can’t make file (document "00000.MTS") into type «class fsrf»
The Standard Additions command open for access does not support QuickTime Player documents anyway. What is the purpose of the open / close lines?
Note:
as Unicode text as coercion to string is outdated since macOS 10.5 Leopard. It's only used with read and write commands to handle UTF16 encoded text. A coercion to standard AppleScript text is simply written as text. In case of name of currentItem it's redundant anyway because the class of name is always text.
I am trying to do below in AppleScript.
Concatenate/Merge all *.xxx files found in a particular folder into one new file
Each file contains a header. Strip header from all but 1st file before merging.
Add a footer text to the merged file.
This sounds relatively simple in other languages but I am a beginner to applescript. Any help to find a direction would be appreciated.
TIA
AnuRV
Try this, you are prompted to choose a base folder and a destination file name.
Important: Use a destination location outside the base folder to avoid the file to be included in the merging process.
I assume that your tsv file type is a typo and you mean csv.
If not, change all occurrences of csv in the script.
The text delimiter is linefeed (0A), if you need return (0D) change the occurrence of linefeed to return.
set baseFolder to choose folder
set destinationFile to choose file name with prompt "Choose destination file name" default name "merged.csv"
tell application "Finder" to set tsvFiles to (files of baseFolder whose name extension is "csv") as alias list
set text item delimiters to linefeed
try
set fileDescriptor to open for access destinationFile with write permission
repeat with i from 1 to (count tsvFiles)
set theFile to item i of tsvFiles
set theText to paragraphs of (read theFile as «class utf8»)
if i = 1 then
write (theText as text) to fileDescriptor as «class utf8»
else
write ((items 2 thru -1 of theText) as text) to fileDescriptor as «class utf8»
end if
end repeat
close access fileDescriptor
on error
try
close destinationFile
end try
end try
set text item delimiters to {""}
I'm trying to read an html file into a variable in AppleScript, I have the following code.
tell application "Finder"
set theItems to every file of folder folderName
repeat with theFile in theItems
open for access theFile
set fileContents to (read theFile)
end repeat
end tell
Now I get an error like:
Finder got an error: Can’t make document file "index.html" of folder
[...] of startup disk into type «class fsrf».
What am I doing wrong? I followed this example. Are HTML files not recognized as text?
You have to convert the Finder file objects to aliases or text.
read can be used without separate open or close commands. It reads files as MacRoman without as «class utf8» though. (as Unicode text is UTF-16.)
tell application "Finder" to files of folder "HD:Users:lauri:Sites" as alias list
repeat with f in result
read f as «class utf8»
end repeat
Try:
tell application "Finder" to set theItems to every file of folder folderName
repeat with theFile in theItems
set aFile to POSIX path of (theFile as text)
set fileContents to do shell script "cat " & quoted form of aFile
end repeat
Starting from your original code, this should do it:
set folderPath to choose folder
set someData to ""
tell application "Finder"
set theItems to every file of folder folderPath as list
repeat with theFile in theItems
set theFilePath to theFile as text
if characters -5 thru -1 of theFilePath as string is ".html" then
set theFileHandle to (open for access file theFilePath)
set fileContents to (read theFileHandle)
-- for testing, call some function
set someData to someData & return & processHtml(fileContents) of me
close access theFileHandle
end if
end repeat
-- do something with someData here
return someData
end tell
on processHtml(theData)
-- do something with theData here
return theData
end processHtml
As Lauri wrote, you can add "as «class utf8»" to read the file as UTF8. You could also use "as Unicode text" for UTF16. Personally, I like this, because it is vanilla AppleScript and doesn't need shell scripting.
Using open for access is really doing it the hard way.
If you want to read an HTML file with AppleScript, then the best way to do that is to use AppleScript to tell an HTML editor to read the HTML file for you. That is the fundamental way that AppleScript works. That’s why “tell” is the most important command. That’s why you can accomplish your goal of reading an HTML file into a variable in just 3 lines:
tell application "BBEdit"
open (choose file)
set theHTMLSource to the text of document 1
close document 1
end tell
The following script expands on the above to read an arbitrary number of HTML files from a chosen folder. It works with BBEdit 9, and should also work with BBEdit’s free version, which is called “TextWrangler” and is available in Mac App Store. Or you can fairly easily adapt this script for use with HyperEdit or TextEdit or whatever AppleScript-aware HTML/text editor you prefer to use.
tell application "Finder"
set theFolder to (choose folder)
set theFiles to every file of folder theFolder
set theHTMLSourceList to {}
repeat with theFile in theFiles
if the kind of theFile is equal to "HTML document" then
set theName to the name of theFile
tell application "BBEdit"
open file (theFile as text)
set theSource to the text of document 1
copy {theName, theSource} to the end of theHTMLSourceList
close document 1
end tell
end if
end repeat
end tell
When the above script is finished, the variable “theHTMLSourceList” is populated with the names and source code of the entire folder of HTML documents, like so:
{{name of file 1, source of file 1}, {name of file 2, source of file 2}, {name of file 3, source of file 3}}
… and so on up to an arbitrary number of files. But of course you can have the script return the HTML source to you in whatever way you like. The key point is that an AppleScript-aware HTML editor can both read HTML and set AppleScript variables, so you don’t have to write (and debug and maintain) your own HTML reader in tiny AppleScript.