Applescript quicklook: arrow key down 1000 times - applescript

I'm a total beginner in apple script.
I would like to open a folder directory that contains hundreds of photos and to view each photo 1 second with quick look and then go to the next (suppose to use down arrow / key code '124').
I don't have any idea of how to build the script. I tried to compile some formulas from other questions or use the manual rec but it doesn't work.
Thanks!

Try following script. I made the delay longer so you have time to stop the script (to test it):
set timePerPreview to 5
set thisFolder to (choose folder with prompt "Pick the folder containing the files to process:") as string
tell application "Finder"
activate
open folder thisFolder
select every item in folder thisFolder
delay 2
set fileCount to (count items in (get selection)) # (count files in folder thisFolder) is faster but counts also .DS_Store and other invisible files
if fileCount = 0 then
beep
return
end if
end tell
pressSpaceInFinder()
delay timePerPreview / 2 # first it has to open the window which seems to need a little time
repeat fileCount - 1 times # -1 because the first item is already displayed
delay timePerPreview
# do shell script "sleep" & space & timePerPreview as text
tell application "System Events"
tell application process "Finder"
set frontmost to true
# cursor right = 124, left = 123
key code 124
end tell
end tell
end repeat
delay timePerPreview
pressSpaceInFinder()
on pressSpaceInFinder()
tell application "System Events"
tell application process "Finder"
set frontmost to true
keystroke space
end tell
end tell
end pressSpaceInFinder
Be aware that it is hard to stop the script since the Finder gets activated every second. Will see if I can add a check to see if the Preview window is open and if not, stop the script.
Also: (without that check) the script will, when the Preview window is open before running, close it but you can just press the space key to open it again.
Also, the first part (getting the file count) isn't so great and may fail when the delay is to short. We could scan the whole folder for images and only count / select those (it has a file template for the scanner, see menu File) but of course you can remove the whole counting thing and just do repeat 1000 times.

Related

Apple Script: how do I watch for new download file with specific name to trigger a script?

I have a script that downloads a report from an online service, waits a specified amount of time e.g. 30secs for the file to actually download and then renames the file. The script then repeats
What I would like to do is instead of putting a static delay in the script, to create a trigger that looks for the new file and once it appears triggers the renaming portion of the script.
The downloaded file name is constant.
The current portion of the script looks like this
`
tell application "Finder" to activate
tell application "System Events"
delay Wait_Time
key code 125
tell application "Finder"
set name of (selection as alias) to (the clipboard)
end tell
end tell
ultimately what I would like is to replace the delay Wait_Time with a something like:
repeat until file name found
Search Folder for "file name"
end repeat
select new file
rename new file to clipboard
obviously this wont work but it kind of captures my logic.
I have also tried a few other possible solutions but Im new to AppleScript and not overly confident that these approaches are suitable for my application.
The below is an example of a solution I have tried. This is just an example and im not sure if this particular code can even get me to where I need to be. I thought I would include it to show just how lost I am.
set excludes to {"Folder", "Application"}
tell application "Finder"
set search_folder to folder "Macintosh HD:Users:XXXXXXXX:Library:CloudStorage:OneDrive-Flinders:Flinders Connect Stats:Source Stats:Cisco Finesse:Agent State Summary by Interval Report"
set foundItems to (every item in search_folder whose name contains "Agent State Summary by Interval Report" and kind is not in excludes) as alias list
if foundItems is {} then return
repeat with once from 1 to 100
try
if (count of foundItems) = 1 then
tell application "Finder" to activate
tell application "System Events"
key code 125
tell application "Finder"
set name of (selection as alias) to (the clipboard)
end tell
end tell
exit repeat
end if
end try
end repeat
return
end tell
Im sure you can see I have no idea what im doing.
Anyway any help would be awesome!
I have found a solution... if anyone has ideas for improvement please let me know.
tell application "Finder" to activate
tell application "System Events"
repeat until (exists (files of folder folderPath whose name contains "Agent State Summary by Interval Report"))
delay 1
end repeat
end tell
tell application "System Events"
key code 125
tell application "Finder"
set name of (selection as alias) to (the clipboard)
end tell
end tell
end repeat
say "Finished!"
display dialog "Completed"
The original solution was found here AppleScript: How to repeat a search for a file until it is found?

How To Monitor Contents Of Folder Without Blocking Finder

As you can see from my code below I am extremely new to this. My code just about works, but my major issue is that it hogs up Finder and sometimes it does not set the Desktop picture, but does most of the time!
The script just monitors a folder, and if an "***.jpg" is added then the Desktop picture set to it.
This is my very first script so I have a lot to learn,
set reset to ""
display notification "Alarm Front Active " & (current date) as string
tell application "Finder"
set path_to_sourceFull to ":photo:FRONT CAM 1:20190929:images" -- from nsa310 network drive
set path_to_source to ":photo:FRONT CAM 1:20190929:images" -- from nsa310 network drive
set directory1 to "/Volumes/photo/FRONT CAM 1/20190929/images" as text -- from nsa310 network drive
set path_to_destinationFull to "Macintosh HD:Users:rekordbox:Documents:temp folder 2"
set path_to_destination to ":Users:rekordbox:Documents:temp folder 2"
set directory2 to "/Users/rekordbox/Documents/temp folder 2" as text
repeat while reset = ""
set allok to ""
set filelist to name of every item in folder path_to_source --of startup disk
set listSizesaved to count of filelist
delay 1
repeat while allok = ""
set filelist to name of every item in folder path_to_source --of startup disk
set listSize to count of filelist
if listSize = listSizesaved then
else
set filelist to name of every item in folder path_to_source --of startup disk
set listSize to count of filelist
set LastAddedFile to item listSize of filelist
set allok to "ALARM"
set listSizesaved to listSize -- (save the updated) count
set activefile to (path_to_source & LastAddedFile)
set selectedpicture to (directory1 & "/" & LastAddedFile)
tell application "System Events" to tell every desktop to set picture to selectedpicture
delay 1
display notification "ALARM FRONT TRIGGERED...." & (current date) as string
delay 1
end if
end repeat
end repeat
end tell
The script you want, I think, is this:
on adding folder items to thisFolder after receiving filelist
set droppedFile to first item of filelist
tell application "System Events"
tell every desktop
set picture to droppedFile
end tell
end tell
end adding folder items to
(I've left out the 'Alarm' bit, since I wasn't sure what the point of it was.)
To use this script, copy it into Script Editor, save it in the folder ~/Library/Scripts/Folder Action Scripts/, then open the applet 'Folder Actions Setup'. Add the folder you want on the left-hand side, and choose the file you just saved on the right. It should look something like this:
...where the checkmark on the left shows that folder actions are enabled for the folder (which I called 'test folder') and the script (which I called 'FADtop.scpt') is attached.
Drop an image in the folder, and it should just work.
As a general rule, don't script the Finder unless you absolutely need to; always use System Events. The Finder is a busy app, and scripting it can gum up the system. And also try to avoid this design pattern:
(* Don't do this! *)
repeat
(* test for something *)
delay x
end
The delay command is not particularly resource-efficient. If you really want to use a polling system to test for some event, it's often better to create a stand-alone app with an on idle handler. That way you let the system wake and sleep the script, with significant performance improvements.
EDIT
Since folder actions don't seem to be working with ftp drops onto remote drives, here's a reasonably efficient folder-polling approach. Save the following script as a stay-open application (choose 'Application' as the file type, and click the 'stay open' checkbox). Then launch the application and leave it running in the background.
property dateOfLastFileChosen : missing value
property targetFolder : "/Volumes/photo/FRONT CAM 1/20190929/images"
property idleTime : 300 -- 300 seconds is five minutes
on run
end run
on idle
tell application "System Events"
if exists folder targetFolder then
if dateOfLastFileChosen is missing value then
set recentFiles to every file of folder targetFolder whose visible is true
else
set recentFiles to every file of folder targetFolder whose modification date > dateOfLastFileChosen and visible is true
end if
set newFile to my mostRecentFileOfList(recentFiles)
if newFile is not missing value then
set dateOfLastFileChosen to modification date of newFile
tell every desktop
set picture to (POSIX path of newFile)
end tell
end if
end if
end tell
return idleTime -- check every 5 minutes (300 seconds)
end idle
on mostRecentFileOfList(fileList)
set maxDateObj to missing value
repeat with thisFile in fileList
if maxDateObj is missing value then
set maxDateObj to contents of thisFile
else if modification date of thisFile is greater than modification date of maxDateObj then
set maxDateObj to thisFile
end if
end repeat
return maxDateObj
end mostRecentFileOfList
Without trying to steal the thunder from #Ted Wrigley, whose solution provided the AppleScript code for the folder action, I felt there were enough comments and items for me to add to post it as another answer to the OP's dilemma.
First I will address the tell every desktop set picture to droppedFile lines of code in the following AppleScript Folder Action. If the user has only one monitor/display attached to the computer, but has created several different "Spaces", the tell every desktop set picture to droppedFile lines of code will only change the Desktop Picture for the Desktop of the current active "Space" only. The other Desktop backgrounds will not be changed. However, if the user has several monitors/displays attached to the computer, the tell every desktop set picture to droppedFile lines of code will change the Desktop Pictures for the Desktops of the current active "Space" for each attached monitor/display. If the latter is not the desired result, then tell every desktop should be changed to tell current desktop.
After testing the AppleScript Folder Action code provided by #Ted Wrigley, I noticed the image file being downloaded from an FTP server, to the test folder where I have the folder action script attached to, looked like this before the image was actually finished transferring. Because the file was kind of there and not there, it did not trigger the Folder Action.
Next, I figured I would add a delay to be beginning of the Folder Action code to allow for the transfer of the image file from the FTP server, to complete. I added a delay of 180 seconds to allow for the transfer to complete and it worked. When the transfer was complete, the file look like this.
Depending on how many files you foresee being transferred at any given time along with factoring in for file sizes... It's possible you may need to significantly increase the Delay time.
on adding folder items to thisFolder after receiving theseFiles
delay 180
set newBackground to first item of theseFiles
tell application "System Events"
set picture of current desktop to newBackground -- Single Display Attached
--set picture of every desktop to newBackground -- Multiple Displays Attached
end tell
end adding folder items to

AppleScript does not run from calendar

I made the following code to open a website, insert some required text, click "View", and download the resulting document. It runs perfectly if I manually click on it. It also works if I schedule a calendar event to call it when I am sitting in front of my Mac. I have tried every combination of keeping the display on/off and screen unlocked/locked. For some reason, it doesn't seem to work at 5:30am and 2:00pm when I set it to run. I have checked to make sure the disk and Mac are not going to sleep as well. Any thoughts on what I am doing wrong would be greatly appreciated.
--Quit Safari before the program starts
tell application "Safari"
close every window
end tell
--empty "Downloads" folder
tell application "System Events"
delete (every file of folder ("/Users/97pubs/Downloads"))
end tell
--opens DINS website
tell application "Safari"
make new document with properties {URL:"https://www.notams.faa.gov/dinsQueryWeb/"}
activate
ignoring white space
tell front document to repeat until its text contains "About DINS"
end repeat
end ignoring
log "Finished loading"
end tell
delay 2
--Function to press DoD banner on DINS website
to clickClassName(theClassName, elementnum)
tell application "Safari"
do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();" in document 1
end tell
end clickClassName
clickClassName("ui-state-default", 0)
delay 2
--Function to input ICAO abbreviations on the page
to inputByName(theName, num, theValue)
tell application "Safari"
do JavaScript "
document.getElementsByName('" & theName & "')[" & num & "].value ='" & theValue & "';" in document 1
end tell
end inputByName
inputByName("retrieveLocId", 0, "kmaf")
delay 2
--Function to click "View NOTAMs" on page
to clickName(theName, elementnum)
tell application "Safari"
do JavaScript "document.getElementsByName('" & theName & "')[" & elementnum & "].click();" in document 1
end tell
end clickName
--Clicks "View NOTAMs" on page
clickName("submit", 0)
--Waits for next window to completely load before continuing
tell current application
tell application "Safari"
tell window 1
repeat until (exists tab 2)
delay 1
end repeat
ignoring white space
tell front tab to repeat until its text contains "DINS Disclaimer"
end repeat
end ignoring
end tell
end tell
end tell
delay 1
--Clicks "Save all NOTAMs" on page
clickName("button", 1)
delay 2
--Waits for download to complete before continuing
set someFolder to "/Users/path/to/save/location/" -- put your download folder path here
if not (waitForFilesToCopy into someFolder for (10 * minutes)) then
display alert "Error with downloads" message "The downloads did not complete in the time allowed."
if button returned of the result is "Cancel" then error -128
end if
to waitForFilesToCopy into theFolder for timeToWait
(*
waits up to the timeToWait for files to be copied/downloaded to theFolder the test is based on the size of the folder not changing after several seconds the rough timeToWait may need to be adjusted if copying several files/folders parameters - theFolder [mixed]: the folder to check timeToWait [integer]: a maximum timeout value in seconds returns [boolean]: true if copy/download finished, false if timeout
*)
set {theFolder, possible, interval} to {theFolder as text, false, 2} -- change the check interval as desired
tell application "System Events" to set currentSize to size of disk item theFolder -- get initial size
repeat (timeToWait div interval) times -- check every interval seconds
delay interval
tell application "System Events" to set newSize to size of disk item theFolder -- recheck size
if (newSize is equal to currentSize) then
if possible then -- no change since last time
return true -- success
else -- one more time...
set possible to true
end if
else -- update size & possible switch
set {currentSize, possible} to {newSize, false}
end if
end repeat
return false -- fail (timeout)
end waitForFilesToCopy
--Rename PDF to "5 Local NOTAMs.pdf"
tell application "System Events" to set name of file "/Users/path/to/save/location/temp.pdf" to "5 Local NOTAMs.pdf"
--Move NOTAMs to "CrewPapers" folder
tell application "Finder"
move POSIX file "/Users/path/to/save/location/5 Local NOTAMs.pdf" to POSIX file "/Users/path/to/new/location" with replacing
end tell
--Close Safari and Preview windows
tell application "Safari"
close every window
end tell
tell application "Preview"
close every window
end tell

Applescript - Numbers won't close "Untitled"

I'm trying to do an applescript that pastes data into Numbers and then exports it as a csv file.
It's all working fine except that Numbers keeps my previous documents and opens them every time. This resulting in a new "Untitled" every time the script runs, so if the script is run 10 times - Numbers will open the 10 previous documents first.
I'm trying quit without saving and close this document without saving without results :(.
How can I make Numbers not open old unsaved files everytime Numbers is started?
on run
set theFilePath to "APPLE SSD SMO128B Media:Users:Henrik:Desktop:my.csv"
tell application "Numbers"
activate -- If script is run once before the old document that is exported but not saved will open here too
set thisDocument to make new document
tell thisDocument
delete every table of every sheet
end tell
end tell
tell application "System Events" to keystroke "v" using {option down, shift down, command down}
delay 1
tell application "Numbers"
export front document as CSV to file theFilePath
close thisDocument without saving
delay 1
end tell
tell application "Numbers" to quit without saving
end run
To avoid having Numbers reopening the files you created, you first need to actually save the document to a file, and then ask the Finder to delete it.
You can use the following code:
set documentName to "Test"
set targetFolder to path to downloads folder
set myFile to ((targetFolder as string) & documentName & ".numbers")
tell application "Numbers"
set myDocument to make new document
#Save the file, to delete it just afterward
save myDocument in file myFile
# Export the document
set exportFileName to documentName & ".pdf"
set the targetFilePath to ((targetFolder as string) & exportFileName)
export myDocument to file targetFilePath as PDF
close
quit saving no
end tell
tell application "Finder" to delete file myFile

Applescript: Get absolute path of item in a File > Open window

I'm trying to automate JPEGmini which is not entirely scriptable - the only way to control it is via the "Open" dialog.
Repeatedly calling it once per image is extremely slow.
Instead I'm trying to to perform a search for .jpg or .jpeg files in the "Open" dialog, so that within that result set I can select the batch of files I want to process and open them in a single pass.
(More detail after the code example)
-- later within the search results list I get, I want to select these
set filesToSelect to {"/Users/me/Desktop/photo.jpg", "/Users/me/Documents/image.jpeg"}
-- the actual app is JPEGmini but the same principle applies to Preview
tell application "Preview"
-- start the app
activate
-- let it boot up
delay 3
-- ensure it still has focus
activate
end tell
tell application "System Events"
tell process "Preview"
-- spawn "Open" window
keystroke "o" using {command down}
delay 1
-- spawn "Go to" window
keystroke "g" using {command down, shift down}
delay 1
-- Go to root of hard drive
keystroke "/"
keystroke return
delay 1
-- Perform search
keystroke "f" using {command down}
delay 1
keystroke ".jpg OR .jpeg"
keystroke return
end tell
end tell
Having done the above, how do I access the list of search results, repeat over each item and get it's absolute file path?
I've tried a few variations but am getting nowhere.
Thanks for your time.
You could simplify this by using cross between the shell command line and applescript.
set jpegSearch to paragraphs of (do shell script "mdfind -onlyin / 'kMDItemContentType == \"public.jpeg\" '")
The mdfind command
consults the central metadata store and returns a list
of files that match the given metadata query. The query can be a string
or a query expression.
AFAIK this is what spotlight uses.
mdfind documents will give you an idea of how this command works. But ths script searches only in "/" and looks for content type attribute that is public.jpeg
The return is text. A list of POSIX Paths of the matching files. This text is like a text document each path on a new line but in effect one item as far as Applescript is concerned.
They need to be broken up in a applescript list. So I do this by asking for the paragraphs of the result.
Also if you want to open a new finder window:
try something like:
tell application "Finder"
activate
set myWindow to make new Finder window to startup disk
end tell
To answer why you are getting your error in trying to get the POSIX paths of the target of the files.
If you look at the properties of one of the files returned in your Search Window.
tell application "Finder" to set fileList to properties of first file of front window
You will see the file properties have a property named original item
If you really want to do it the way you are doing it then one way is to get the original item. Coerce the result into alias form then get the posix path.
tell application "Finder" to set aFile to POSIX path of (original item of first file of front window as alias)
In a normal finder window you can use.
tell application "Finder" to set fileList to POSIX path of (first file of front window as alias)
These are just examples to show you whats going on.
The difference in the type of finder window results is because in a Search window what is being displayed is alias files (class:alias file) to the original files, hence the original item property.
Update 2.
To go through your items in your list and check them against another list is simple.
Apple have some tools that will help you with the code.
When in your script.
crtl + Mouse Click the Variable that will hold the jpg result as a list.
This will give you a contextual menu that contains helper code.
Go to the Repeat routines folder in the menu.
Then to its 'Process Every Item'
This will add a repeat routine to your code.
And from there you can use it to check each item against your other list.
set yourOtherList to {"/Library/Desktop Pictures/Abstract/Abstract 2.jpg", "/Library/Desktop Pictures/Abstract/Abstract 1.jpg"}
set jpegSearch to paragraphs of (do shell script "mdfind -onlyin / 'kMDItemContentType == \"public.jpeg\" '")
repeat with i from 1 to number of items in jpegSearch
set this_item to item i of jpegSearch
if this_item is in yourOtherList then
-- do something
log this_item
end if
end repeat
The repeat routine works like this.
It loops over each item in the given list
It will iterate from item 1 to the count of the items in the list.
The i variable holds the loop iteration number. I.e it will be 1 on the first loop and 300 on the 300th loop.
so on the first loop set this_item to item i of jpegSearch is equivalent to writing set this_item to item 1 of jpegSearch
But apple saves you having to write each number of each item with the Repeat with i..
The variable i can be any word or letter you choose that conforms to the normal allowed Variable naming syntax.
Something you can do is build a new list from the matched items. by copying them into a previously declared list. You can then work on that list after the repeat loop has completed.
Here bigList is declared as a empty list {}
The matched items are copied to the bigList. Each new item it receives is added to the end of the list.
set bigList to {}
set yourOtherList to {"/Library/Desktop Pictures/Abstract/Abstract 2.jpg", "/Library/Desktop Pictures/Abstract/Abstract 1.jpg"}
set jpegSearch to paragraphs of (do shell script "mdfind -onlyin / 'kMDItemContentType == \"public.jpeg\" '")
repeat with i from 1 to number of items in jpegSearch
set this_item to item i of jpegSearch
if this_item is in yourOtherList then
copy this_item to end of bigList
end if
end repeat
bigList

Resources