11

I am trying to create a task in automator that moves files in ~/Downloads to the trash if they are older than 30 days.

I want this to run every day.

It's not working though, Finder just hangs and stops responding and I have to Force Quit it from activity monitor.

on run {input, parameters}

    tell application "Finder"
        set deleteFileList to (files of entire contents of folder alias "Macintosh HD:Users:George:Downloads" whose modification date is less than ((get current date)) - 30 * days)
        try
            repeat with deleteFile in deleteFileList
                delete deleteFile
            end repeat
        end try
    end tell

    return input
end run
theonlygusti
  • 11,032
  • 11
  • 64
  • 119

3 Answers3

22

I'd take a different approach and use a set of actions available in Automator without the use of AppleScript.

The following workflow will accomplish that you're looking to do.

In Automator, create a new Workflow adding the following actions:

  • Get Specified Finder Items
    • Add the Downloads folder to it.
  • Get Folder Contents
    • [] Repeat for each subfolder found
  • Filter Finder Items
    • Find files where:
      • All of the following are true
        • Date last modified is not in the last 30 days
  • Move Finder Items to Trash

Save the Workflow as an Application, e.g.: Cleanup Downloads.app

This should run much faster then AppleScript version, it did in my testing.


Apple's preferred method to schedule something such as this is to use launchd and launchctl.

To run Cleanup Downloads, daily, I'd do the following:

  1. Add Cleanup Downloads to: System Preferences > Security & Privacy > Privacy > Accessibility
  2. Create a User LaunchAgent in: ~/Library/LaunchAgents/

    • Example: com.me.cleanup.downloads.plist as an XML file containing:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
          <key>Label</key>
          <string>com.me.cleanup.downloads</string>
          <key>ProgramArguments</key>
          <array>
              <string>/Applications/Cleanup Downloads.app/Contents/MacOS/Application Stub</string>
          </array>
          <key>RunAtLoad</key>
          <false/>
          <key>StartCalendarInterval</key>
          <array>
              <dict>
                  <key>Hour</key>
                  <integer>10</integer>
                  <key>Minute</key>
                  <integer>00</integer>
              </dict>
          </array>
      </dict>
      </plist>
      
    • Set the value for Hours and Minutes, under StartCalendarInterval, as appropriate for your need. The example is set for: 10:00AM

  3. In Terminal run the following command to load the LaunchAgent:

    launchctl load ~/Library/LaunchAgents/com.me.cleanup.downloads.plist
    

Note: See the manual pages for launchd and launchctl in Terminal, e.g. man launchctl

Or use a third party utility that has a GUI, e.g.: Lingon X

Note: I'm not associated with the developer of Lingon X, however I am a satisfied customer.


Some comments on your AppleScript code:

A repeat statement isn't necessary, just use:

move deleteFileList to trash

The current date command technically executes under current application, not Finder as Finder does not understand the current date command . Therefore, set a variable and use the variable in the command.

set thisDate to get (current date) - 30 * days

... whose modification date is less than thisDate

Now I'm not proposing you actually use the AppleScript over the workflow I proposed, I'm just pointing out some things in the code I take issue with.

user3439894
  • 7,266
  • 3
  • 17
  • 28
  • @theonlygusti, I've update my answer to include info to schedule the use of the workflow application. – user3439894 Sep 26 '17 at 17:18
  • 1
    I'm assuming "[] Repeat for each ..." means _don't_ repeat for each subfolder found? So, [is this what it should look like?](http://i.cubeupload.com/hrJBcx.png) – theonlygusti Sep 26 '17 at 19:18
  • @theonlygusti, In **Automator**, create a new **Application** _workflow_, adding the following _actions_: ... :) Yes, save it as an Application. – user3439894 Sep 26 '17 at 19:39
  • What is an application workflow? I just went _File > New > Workflow_ ... is that wrong? – theonlygusti Sep 26 '17 at 19:56
  • @theonlygusti, If I click Automator > File > New, I can choose from Workflow, Application, Service, etc..., however when I say Application workflow, I mean choose Application. That said, they are all workflows and you can choose Workflow or Application, just save it as an Application. Sorry for any confusion. – user3439894 Sep 26 '17 at 20:18
  • @theonlygusti, In short, an Automator Workflow is a series of actions that runs inside of Automator. An Automator Application is the same as a Workflow, but it can be run as an application from outside Automator. If you choose e.g. Workflow and then save it as an Application, it's converted to an Application workflow. Please note the different in case when saying Workflow and or workflow, they represent two different things. The lowercase starting "workflow" represents a series of actions that take place, the upper starting "Workflow" is the type of Automator document being created. – user3439894 Sep 26 '17 at 20:42
  • @theonlygusti, Sorry I missed your comment when you said, "I'm assuming "[] Repeat for each" means don't repeat for each subfolder found?" and the answer to that is yes, leave that checkbox unchecked just as I've shown it in the answer. Otherwise I would have checked it as in: [√] Repeat for each subfolder found - Aside from the fact in some cases it can throw an error if it's checked, the the rational is that in the parent folder, e.g. Downloads in this case, any folder at that level that meets the filter criteria is going to be acted upon anyway and thus no need to go into the folder itself. – user3439894 Sep 27 '17 at 14:41
  • isn't it possible to download a very old file with intact meta data, that was last modified a year ago but added to your folder just a day ago? And wouldn't that file be removed as well? – Jere Aug 21 '18 at 08:32
  • 1
    @Jere, Yes that is certainly possible however, I believe the OP is aware of that and even if not... **The onus is always upon the user to insure proper backups are in place before implementing any solutions that (may) have a destructive component!** For example, I have Time Machine running, which runs every 15 minutes, and I always make sure I'm currently backed up before testing something that might do something other then expected/wanted. Personally I normally would not implement any automated solution of the wholesale deletion of files within my Home folder, I usually manage that manually! – user3439894 Aug 21 '18 at 13:54
  • This is an excellent solution, is there a way to avoid a warning when there aren't any files that match the criteria? If this is run daily and 30 days ago I happened not to download any files, I get a warning indicating that nothing could be moved to Trash... – quiram Jul 29 '19 at 11:39
  • 1
    @quiram, To resolve the issue you mentioned, add a **Run Shell Script** _action_ to the start of the _workflow_, with the following line of _code_: `touch -t $(date -v-31d +%Y%m%d%H%M.00) ~/Downloads/Foobar_$(date +%s000); sleep 3` Then in the **Options** for the **Get Specified Finder Items** _action_, check the **[√] Ignore this action's input** checkbox. This will create a dummy file with a modified date of -31 days from the time it's run, thus there will alway be at least one file with a modified date of more than 30 days from the time it's run. – user3439894 Jul 29 '19 at 13:41
  • @quiram, Note that the `; sleep 3` _argument_ is necessary for Spotlight to update, otherwise the file is overlooked until the next time run. If `3` seconds is not enough try `5`. – user3439894 Jul 29 '19 at 13:41
  • ah, that's clever, thanks @user3439894! I had to adapt the script slightly because I have GNU `date` as opposed to standard macOS `date`, but writing it as `date --date="31 days ago" +%Y%m%d%H%M.00` did the trick for me. Thanks! – quiram Aug 01 '19 at 07:40
  • For me it was `/Applications/Cleanup Downloads.app/Contents/MacOS/Automator Application Stub` instead of `/Applications/Cleanup Downloads.app/Contents/MacOS/Application Stub`. Note the `Automator Application Stub` part. Running macOS 12.0.1 Monterey. – adriaan Nov 17 '21 at 10:31
0

If Finder hangs, this is probably because there are too much files in the "entire contents". It could be that some downloaded items are made of folders with sub-folders / subfolders,... then too many files.

Instead I suggest you to only look at first level of the download folder : the items top level:

Set DeleteFileList to every items of folder "Macintosh HD:Users:George:Downloads" whose modification date is less than ((get current date)) - 30 * days)

The content of DeleteFileList will be made of files and folders, but I guess you want to delete full folders and not only files inside them.

pbell
  • 2,965
  • 1
  • 16
  • 13
  • 1
    `folder alias alias` might work but is not good syntax. Either `folder` or (one) `alias`. And there is a *shortcut* `... every items of (path to downloads folder) ...` – vadian Sep 26 '17 at 20:29
  • Thanks Vadian. "alias alias" was my mistake. I just remove it. – pbell Sep 27 '17 at 06:05
0

If you don't want to mess with the scheduling of the task, you could create a Folder Action (instead of a Workflow) in Automator for the Downloads-Folder that deletes files older than 30 days if a new file hits the folder. The workflow would essentially be the same as in @user3439894s suggestion.