0

I am writing AppleScript to change my desktop background to a random photo from a random subfolder. My photo folder structure consists of nested subfolders which can be several levels deep. At the moment I have a simple script which selects a random file from ONE folder. But how can I make it select a random picture from a random subfolder (which could be several levels deep)? Any help appreciated!

Here's what I have so far which changes the desktop background to a random photo from one single folder, but I need it to also look through nested subfolders:

tell application "Finder"
    set randomimage to some file of folder "Macintosh HD:Users:mrawesome:My Photos:Australia" as string
end tell

tell application "System Events"
    tell every desktop
        set random order to false
        set picture to randomimage
    end tell
end tell

2 Answers 2

0

Try this

property theFolder : "Macintosh HD:Users:mrawesome:My Photos:Australia"

set randomImage to some item of paragraphs of (do shell script "find " & ¬
    quoted form of POSIX path of theFolder & ¬
    " -iname \"*.jpg\" -or -iname \"*.png\" -or -iname \"*.tiff\"")

tell application "System Events" to tell every desktop
    set {random order, picture} to {false, randomImage}
end tell
1
  • Amazing! Thank you @wch1zpink - That works absolutely perfectly and extremely fast too. My photo folder & subfolders contain over 45,000 photos and your script comes back instantly. Thanks again, much appreciated. Commented Feb 10, 2022 at 3:35
0

There are a few ways to get files from nested subfolders.

The Finder has the entire contents container property, but be aware that it can choke on large folder structures:

set theFolder to (choose folder)
tell application "Finder" to set theFiles to (get every document file in entire contents of theFolder as alias list)
set randomImage to (some item of theFiles)

System Events can also be used, although you would need to manually descend the directory tree. Like the Finder, you would also need to look for the desired type of files (images, etc) if you dont want everything (document types are mixed, for example):

set theFolder to (choose folder)
set theFiles to getFiles from theFolder # given extension:"png", UTI:"public.jpeg" -- or whatever
set randomImage to (some item of theFiles)

# Get files (optionally with the extensions or UTIs), recursively descending the directory tree
to getFiles from someItems given extension:extension : {}, UTI:UTI : {}
   set foundList to {} -- this will be a list of found items
   repeat with anItem in (someItems as list)
      set anItem to anItem as text
      tell application "System Events"
         if class of disk item anItem is in {"folder", folder} then -- folder
            set subFolders to (get path of disk items of folder anItem whose visible is true)
            set foundList to foundList & my (getFiles from subFolders given extension:extension, UTI:UTI)
         else -- file
            if (UTI is {} and extension is {}) or ¬
               (type identifier of file anItem is in UTI) or ¬
               (name extension of file anItem is in extension) then
               set foundList to foundList & {anItem as alias}
            end if
         end if
      end tell
   end repeat
   return foundList
end getFiles

Your best bet might be the mdfind shell script, which in addition to being fairly speedy, can match more generic UTIs (although the files do need to be indexed by Spotlight):

set theFolder to (choose folder)
set imageFiles to paragraphs of (do shell script "mdfind -onlyin " & quoted form of POSIX path of theFolder & space & quote & " kMDItemContentTypeTree == 'public.image'" & quote)
set randomImage to (some item of imageFiles) as POSIX file
1
  • Thank you very much @red_menace for answering. I didn't get to try your answer as wch1zpink's solution worked for me. But your answer looks like it'll do the job and will definitely help others in the future. Thanks again. Commented Feb 10, 2022 at 3:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .