I used to use two AppleScript scripts to find out the file name of the actual wallpaper image from desktop 1 and desktop 2 (dual monitor mode) under macOS Mojave. One script for the main monitor and another one for the second monitor. Under macOS Catalina the scripts are not working anymore.
Here is the script:
tell application "System Events"
set posix_path to (pictures folder of desktop 2)
set picPath to (POSIX file posix_path) as string
end tell
set thePictures to (do shell script "sqlite3 ~/Library/Application\\ Support/Dock/desktoppicture.db \"SELECT data.value FROM preferences INNER JOIN data on preferences.key=16 and preferences.picture_id=7 and preferences.data_id=data.ROWID\"")
set fullPath to picPath as string
set rotationImage to fullPath & thePictures
tell application "Finder"
try
set aliasItem to item rotationImage
if class of aliasItem is alias file then
reveal original item of aliasItem
end if
end try
end tell
Here is the error message:
tell application "System Events"
get pictures folder of desktop 1
--> "/Users/peter/Library/Caches/com.apple.preference.desktopscreeneffect.desktop/69948584/DSKPhotosRootSource"
get POSIX file "/Users/peter/Library/Caches/com.apple.preference.desktopscreeneffect.desktop/69948584/DSKPhotosRootSource"
--> error number -1728 from POSIX file "/Users/peter/Library/Caches/com.apple.preference.desktopscreeneffect.desktop/69948584/DSKPhotosRootSource"
end tell
tell current application
do shell script "sqlite3 ~/Library/Application\\ Support/Dock/desktoppicture.db \"SELECT data.value FROM preferences INNER JOIN data on preferences.key=16 and preferences.picture_id=1 and preferences.data_id=data.ROWID\""
--> "13725B"
end tell
tell application "Finder"
get item "Macintosh HD:Users:peter:Library:Caches:com.apple.preference.desktopscreeneffect.desktop:69948584:DSKPhotosRootSource13725B"
--> error number -1728 from item "Macintosh HD:Users:peter:Library:Caches:com.apple.preference.desktopscreeneffect.desktop:69948584:DSKPhotosRootSource13725B"
end tell
Tried to find the problem but couldn't find a solution. I am not an experienced AppleScript writer. Hope somebody can help.
On Catalina and Mojave, I'm able to get the current wallpaper by using a sqlite command similar to yours:
sqlite3 ~/Library/Application\ Support/Dock/desktoppicture.db "select * from data" | tail -2
Or in Applescript:
do shell script "sqlite3 ~/Library/Application\\ Support/Dock/desktoppicture.db 'select * from data' | tail -2"
On my Mac, the last 2 items in the data table appear to be some combination of the most recently set wallpaper and last 2 displays that were most recently set, so I tail the list. Like you, I'm also using a large folder of wallpapers and I have it set to change every 30 minutes. As long as I don't manually change a wallpaper, the last 2 items are consistently the names of the 2 active wallpapers because both monitors change at the same time every 30 minutes.
Something to note: When you are using a Folder with the "Change picture:" checkbox checked, the items returned from select * data is just the file name (i.e., wallpaper.jpg). If you've set the wallpaper to a single image, the item returned from the select command is the full path of the image (i.e., /path/to/folder/wallpaper.jpg). Since I'm using a folder, so I get just the image names in my select results. Then I can split the 2 names by newline to get each wallpaper name in an array and then open them. Here's my whole script:
#!/bin/bash
#reads and opens the last 2 items from the 'data' table in the desktoppicture.db sqlite db
last_two=`sqlite3 ~/Library/Application\ Support/Dock/desktoppicture.db "select * from data" | tail -2`
IFS=$'\n' read -rd '' -a y <<<"$last_two"
#echo "first is ${y[0]}"
#echo "second is ${y[1]}"
open /Users/myusername/Pictures/Desktop\ Pictures/${y[0]}
open /Users/myusername/Pictures/Desktop\ Pictures/${y[1]}
I realize you asked an AppleScript question and this is largely a bash script answer, but the do shell script item at the top of my answer should get you going enough to be able to capture and manipulate the image names inside of AppleScript.
Just to close this out, I use this bash script in Alfred using a keyword "retire" to retire a wallpaper I'm tired of. I type the keyword, this script runs to open the images in Preview, another script runs to open my Desktop Pictures folder and a Desktop Pictures Retired folder and then I manually move the photo into the Retired folder.
If you currently have two monitors connected and you're simply looking to retrieve the names of the Desktop Wall Papers for each, this following Apple script code should be what you're looking for.
tell application "System Events"
set everyDesktop to desktops
set desktopOnePicture to picture of item 1 of everyDesktop
set desktopTwoPicture to picture of item 2 of everyDesktop
end tell
I can't guarantee the code below will fair any better than the solution already posted, but it should, in theory, target desktop images per screen (monitor) rather than by desktop (space). However, I don't have Mojave or Catalina, or a computer to test this out:
use framework "AppKit"
property NSScreen : a reference to NSScreen in the current application
property NSWorkspace : a reference to NSWorkspace in the current application
property currentScreen : a reference to the mainScreen of NSScreen
on screen(i as integer)
local i
if i = 0 then return the currentScreen()
return NSScreen's screens()'s item i
end screen
on desktopImageURLForScreen:(i as integer)
local i
set S to screen(i)
tell NSWorkspace's sharedWorkspace() to return the ¬
desktopImageURLForScreen_(S) as «class furl»
end desktopImageURLForScreen:
return the POSIX path of my desktopImageURLForScreen:0
The bottom line is the one you will most likely want to experiment with, by changing the index number passed to the handler. If you have three monitors, then they would each be identified by one of the indices 1, 2, or 3 (I can't predict how index corresponds to arrangement of monitors). Index 0 will always refer to the screen that currently has keyboard focus.
Related
I need some help with an apple script that I can save on the computer so others can remove the ._ files from USB drives that are used for slide shows on TVs. I come from Linux so I pseudoed what I could.
usb_drives=$(ls /volumes/ | grep external) # intent
MyFlashDrive=$(prompt "Please select drive" usb_drives) # intent
dot_clean -m /Volumes/${MyFlashDrive} # mostly accurate
The AppleScript version of this would be something like the following:
tell application "System Events"
set ejactableDisks to get (displayed name of every disk whose ejectable is true)
--name of every file of home folder whose name begins with "."
end tell
set targetDiskName to choose from list ejactableDisks
tell application "System Events"
set targetDisk to first disk whose name is targetDiskName
set dotUnderscoreFiles to every file of targetDisk whose name begins with "._"
if (count of dotUnderscoreFiles) is greater than 0 then
delete dotUnderscoreFiles
end if
end tell
Of course, if you're more comfortable with unix you could write a bash routine and run it through do shell script, or just make an executable bash script.
I am trying to access the Privacy -> Accessibility tab using Applescript. Can anyone help me?
I need to display a list of all the programs in the section:
Accessibility
Camera
Microphone
Photos
etc...
The request itself and the output in the terminal using osascript -e.
It is necessary to exclude interaction with the GUI. Here's what I managed to find
osascript -e 'tell application "System Events" to get the name of every login item'
I need to find the same solution for Accessibility? And get the result the same as in the screenshot below.
The main goals are
Locally get the information contained in Security & Privacy
2)Connect to mac OS via SSH and get the information contained in Security & Privacy. If this is not possible, then how to display the information using a single Apple script.
It is necessary to exclude interaction with the GUI (on the remote system).
Testing with the remote system being macOS Big Sur 11.6 and having checked [√] Allow full disk access for remote users in System Preferences > Sharing > Remote Login on the remote system, then the example shell script code executed in Terminal on the local system in a ssh session to the remote system will give you a raw dump of what's listed under Accessibility in System Preferences > Security & Privacy > Privacy without the need for UI Scripting with AppleScript.
sqlite3 '/Library/Application Support/com.apple.TCC/TCC.db' 'SELECT client FROM access WHERE service="kTCCServiceAccessibility";'
On the test system its output was:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/Support/AEServer
com.apple.AccessibilityInspector
com.apple.Automator
com.apple.ScriptEditor2
com.apple.Terminal
com.latenightsw.ScriptDebugger8
If you really have a need to use AppleScript you could, however, say you needed the output to be pretty. In other words, using an AppleScript script saved as a shell script using a #!/usr/bin/osascript shebang the output on the same remote system would be e.g.:
AEServer, Accessibility Inspector, Automator, Script Editor, Terminal, Script Debugger
Example AppleScript code:
#!/usr/bin/osascript
set theAccessibilityList to paragraphs of (do shell script "sqlite3 '/Library/Application Support/com.apple.TCC/TCC.db' 'SELECT client FROM access WHERE service=\"kTCCServiceAccessibility\";'")
set theAccessibilityApplicationNamesList to {}
repeat with thisItem in theAccessibilityList
if thisItem starts with "/" then
set shellCommand to (do shell script "f=" & quoted form of thisItem & "; echo ${f##*/}")
set end of theAccessibilityApplicationNamesList to shellCommand
else
try
set end of theAccessibilityApplicationNamesList to the name of application id thisItem
end try
end if
end repeat
return theAccessibilityApplicationNamesList
Notes:
I created, saved and made executable the example AppleScript code, shown above, on the local system and then copied it the from the local system to the remote system using scp.
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional 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. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.
You should escape the nested quotes following way. And, activate the System Preferences.
osascript -e "
tell application id \"com.apple.systempreferences\"
activate
reveal anchor named \"Privacy_Accessibility\" in pane id \"com.apple.preference.security\"
end tell
tell application id \"sevs\" to tell process \"System Preferences\"
repeat until window \"Security & Privacy\" exists
delay 0.02
end repeat
tell scroll area 1 of group 1 of tab group 1 of window \"Security & Privacy\"
get value of static text 1 of UI element 1 of rows of table 1
end tell
end tell"
Or, if needed table view (on right) of needed item (on left) is already opened, you can use following osascript on the Catalina:
osascript -e "
tell application id \"sevs\" to tell process \"System Preferences\"
set frontmost to true
tell scroll area 1 of group 1 of tab group 1 of window \"Security & Privacy\" to get value of static text 1 of UI element 1 of rows of table 1
end tell"
I have a problem with a workflow that stopped working when I upgraded to a MacBook Pro M1.
This workflow was used as a Quick Action in Finder files. First I tried running directly from Automator, and to my surprise it works, then tried again as Quick Action and doesn't work. I have been searching the Internet for more than a month and trying with different approaches but can't make it work again from Quick Action.
I have extracted just the code with the problem for easier explanation. The intention is to get the size of a movie file. The following code works inside Automator but issues an error when run from a Quick Action: cannot find the file.
tell application "Finder"
set existingMovies to (every file of theFolder) as alias list
end tell
repeat with movie in existingMovies
--repeat with movie in input
set theMovie to the (quoted form of POSIX path of movie) as string
set movieSize to do shell script "/usr/bin/mdls -name kMDItemDurationSeconds -raw -nullMarker 0 " & theMovie
end repeat
Then I tried working with input parameter of the workflow (in this case a list of files since this workflow uses "Workflow receives current: movie files"). With this approach it works both from Automator and as Finder Action
repeat with movie in input
set theMovie to the (quoted form of POSIX path of movie) as string
set movieSize to do shell script "/usr/bin/mdls -name kMDItemDurationSeconds -raw -nullMarker 0 " & theMovie
end repeat
In all scenarios I am using the same folder.
It seems that the list of files specified by input is somehow different from the list of files I create from a specified folder (existingMovies).
Any idea why this happens?
I can't replicate your problem on my machine, so I can't say for sure what's going wrong. But here's a 'best practices' reworking of your script. See if it solves your problem.
on run {input, parameters}
-- always use System Events, not the Finder, where possible
tell application "System Events"
repeat with thisFolder in input
set existingMovies to (every file of thisFolder)
repeat with movie in existingMovies
-- dereference properties with 'get'
set theMovie to the (quoted form of (get POSIX path of movie))
set movieSize to do shell script "/usr/bin/mdls -name kMDItemDurationSeconds -raw -nullMarker 0 " & theMovie
end repeat
end repeat
end tell
return input
end run
I'm trying to use AppleScript to set the label of a file to a specific colour; or rather, I already have a script that used to work, but ever since upgrading to High Sierra it no longer does.
I've stripped it down to the absolute basics (always sets label to green):
on run theArguments
set theFile to POSIX file (item 1 of theArguments)
tell application "Finder" to set (theFile's label index) to 6
end run
If you save this to a file (green.scpt) then you can run it from Terminal with the following command:
osascript ~/Downloads/green.scpt ~/Downloads/green.scpt
(substitute the paths for wherever you store the script)
This should turn the script's label in the Finder to green, but doesn't (at least on High Sierra), instead giving the following error message:
/Users/haravikk/Downloads/green.scpt: execution error: Finder got an error: Can’t set label index of file "Users:haravikk:Downloads:green.scpt" to 6. (-10006)
Am I doing something wrong here? If not, and this is a bug, then is there some other way to change a file's label via script?
You can try to use tell application before change label index
on run theArguments
tell application "Finder"
set thisItem to POSIX file theArguments as alias
if label index of thisItem is not 6 then
set the label index of thisItem to 6
end if
end tell
end run
This works for me (added "as alias"):
on run theArguments
set theFile to POSIX file (item 1 of theArguments) as alias
tell application "Finder" to set (theFile's label index) to 6
end run
Note though that labels are long gone, and have been replaced with tags.
I am using Applescript to automate some tasks in the OSX Finder. The script opens up a folder and selects the first image in that folder. I would like it to also bring up the "quick look" window (exactly as if the user had pressed the space bar).
I did find a way to fire up quick look from the command line using qlmanage, but that brings up a static quick look window, which is no longer tied to the finder selection.
Code so far:
property folderPath : "/Volumes/Media/Images"
on run {}
tell application "Finder"
activate
set imageFolder to folder (folderPath as POSIX file)
set imageFile to first item of imageFolder
select imageFile
-- show quick look?
end tell
end run
If you don't want to do it by scripting the Finder you can run the following shell command
qlmanage -p thefile
In an Applescript you might do this like
do shell script "qlmanage -p " & "thepath/thefile"
Depending upon what you are doing this might be much easier. Especially if you primarily just have a set of paths.
If you have an existing Applescript path you can send it like this
set p to POSIX path of mypath
do shell script "qlmanage -pr " & quoted form of p
Updated (with thanks to Kevin Ballard):
tell application "System Events" to keystroke "y" using command down
Note: this requires that "enable access for assistive devices" is selected in the "Universal Access" control panel.