delete old files with folders action?

When i put a file into a folder, i would like to check all files an delete the older than X days. (its for download folder). Its posible? ¿there is a way to check all files in a folder or only can check the new files in the folder?

THANK YOU

Model: Mac mini
Browser: Safari 602.4.8
Operating System: Mac OS X (10.10)

Hi. Welcome to MacScripter.

It looks as if Automator folder actions only receive the items which triggered them. But it’s possible to do what you want.

  1. Start a new “Folder Action” workflow.
  2. Use the pop-up menu at the top of the window to choose the folder to which you want to attach it.
  3. Drag a “Run AppleScript” action into the workflow window.
  4. Replace the code in the action window with this:
on run {input, parameters}
	
	set X to 7 -- Change this to the number of days you need it to be.
	
	set XDaysAgo to (current date) - X * days -- Exactly X * 24 hours before the time the script runs.
	set time of XDaysAgo to 0 -- The start of the day X days before the time the script runs.
	
	tell application "Finder"
		-- Get one of the items which has been added to the folder.
		set item1 to item 1 of input
		-- Use it to identify the folder.
		set containerFolder to container of item1
		-- Delete every item in the folder that was last modified before XDaysAgo.
		delete (every item of containerFolder whose modification date comes before XDaysAgo)
	end tell
	
	return input
end run
  1. Save the workflow.

The workflow will be set up and ready to run, but can take a few seconds to react to items being added to the folder.

It’s also possible to write an AppleScript-only folder action, which doesn’t involve Automator. But you’d have to attach it and set it up yourself ” and I’ve forgotten how to do that now. :slight_smile: The code would look like this:

on adding folder items to this_folder after receiving these_items
	
	set X to 7 -- Change this to the number of days you need it to be.
	
	set XDaysAgo to (current date) - X * days -- Exactly X * 24 hours before the time the script runs.
	set time of XDaysAgo to 0 -- The start of the day X days before the time the script runs.
	
	tell application "Finder"
		-- Ignore the added items and just delete every item in the folder that was last modified before XDaysAgo.
		delete (every item of this_folder whose modification date comes before XDaysAgo)
	end tell
	
end adding folder items to

Thank you !

Butt that creates a new problem for me. First i need to make a filter as it appears in the example (not all files and folders need to be deleted) and on the other hand, only move the files, don’t delete them (As I say at first). I do not see how to solve these aspects of the problem using applescript. ¿Any more help :slight_smile: ? Thank you.
(can you see the sample at https://www.dropbox.com/s/r4l94uor2a3dcya/ejemplo.png?dl=0 )

Hi.

The Filter Finder Items (Filtrar ítems del Finder) action in my version of Automator (2.6) never returns any results, even when passed items which should get through the filter. I don’t know whether this is just a problem on my computer or the action actually has a bug. But an AppleScript can easily perform the filtering shown in your screenshot. It could also move the qualifying items if you liked, although the destination folder would have to be coded into it. Alternatively, it can just pass the items on to the Trasladar ítems del Finder action and you can set the destination in that.

The filter in your screenshot specifies items created within the past two days, whereas your first post says files older than a certain number of days. Could you please clarify what you want here? As I understand it at the moment:

You want to move certain items and not delete any others.
Items to be moved must have been created within the past two days and must not be named “Anteriormente.” and must not be named “NO GUARDAR”. (Are “Anteriormente.” and “NO GUARDAR” two items with those exact names?)

This is what folder action should do:

https://www.dropbox.com/s/5unmzt22ahinz7o/ejemplo2.png?dl=0

OK. That’s no problem. Just use an AppleScript action with this code:

on run {input, parameters}
	
	set X to 2 -- Number of days ago.
	set XDaysAgo to (current date) - X * days -- Exactly 48 hours before the time the script runs.
	set time of XDaysAgo to 0 -- 00:00:00 on the day two days before the script runs.
	
	tell application "Finder"
		-- Get one of the items which has been added to the folder.
		set item1 to item 1 of input
		-- Use it to identify the folder.
		set containerFolder to container of item1
		-- Move qualifying items to the folder "Anteriormente." in the same folder.
		move (every item of containerFolder whose name is not "Anteriormente." and name is not "NO GUARDAR" and modification date comes before XDaysAgo) to folder "Anteriormente." of containerFolder with replacing
		
		return result
	end tell
end run

NB. In the script, I’ve used the horizontal ellipsis character (“.”) at the end of “Anteriormente.”. If the name of that folder actually ends with three period (“.”) characters, you’ll need to change that in the script.

Thank you so much for everything. Now it works properly just as I wanted it to. I will try to do other folder actions using Appelscript. Thank you.

:D:D:D

Hello again.

All your script works perfect (thank you again), but with the use I have seen a failure on my part to raise the problem: On my system the compressed files are decompressed in the same folder where the * .zip file is located. When unzipped the * .zip file normally contains files with a creation date before two days, and consequently they are moved to the folder (“Previously …”).
To solve the problem, the correct date to be checked should be the “date added”. In this way, all the dates of files that enter the folder, including the recently unzipped files, will be referenced to “today”, and will not be erased until after two days.
Is it possible to solve this problem easily without having to change the path of the decompressed files?

Thank you !!

Hi.

Sorry for the slow reply. As you can see below, getting ‘dates added’ isn’t quite the same as getting modification dates! :wink:

While modification dates are properties of disk items themselves, ‘dates added’ are information collected and stored by Spotlight. The only way I know to get them is with a shell script. The only way I know to interpret and use the results is with AppleScriptObjC. And if using AppleScriptObjC for that, it makes sense to use it for other things in the script too ” such as getting and moving the items, which it can do much faster than the Finder can. And that leads to several different ways of doing things, all of which require quite a lot of code! But it’s only the verbosity of the language. The execution is pretty fast.

I found in my testing that quite a few of my own files and folders don’t have ‘dates added’. Some are in folders that I’ve told Spotlight not to scan, but I think the others, which are several years old, have simply been in their folders since before Spotlight was invented! I don’t think this will affect you, but I’ve allowed for it just in case. At the moment, the script’s set up to move any items it finds which don’t have ‘dates added’, but you can change the movingWhenNoDateAdded value at the top to false to have them left alone.

Let me know if there are any problems.

Edit: Script modified to use Shane’s NSURLAddedToDirectoryDateKey suggestion in the post below, which removes the need for the shell script and thus for the set-up and interpretation in that respect. It’s still not short, but it’s shorter and slightly faster.
Edit 2: Further modified to use NSURLs throughout. There was a non-fatal but embarrassing mix-up of paths and URLs in the original modification!

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

(* Script configuration properties. Adjust as required. *)
-- The minimum number of days items must have been in the folder before they're moved.
property X : 2
-- How to interpret "days": "calendar days" [true] or "24-hour units from run time" [false]?
property daysMeansCalendarDays : true
-- What to do if an item has no 'date added': move it anyway [true] or not [false]?
property movingWhenNoDateAdded : true
-- What to do with any items already in "Anteriormente." which have the same names as items being moved: zap them [true] or move them to the trash [false]?
property zappingReplacedItems : true

(* Entry point for a "Run AppleScript" Automator action. *)
on run {input, parameters}
	return moveOldItems(input)
end run

(* Main handler. *)
on moveOldItems(input)
	set |⌘| to current application
	
	-- Use one of the items which triggered the folder action to identify the folder.
	set sample to item 1 of input
	set sampleURL to |⌘|'s class "NSURL"'s fileURLWithPath:(POSIX path of sample)
	set folderURL to sampleURL's URLByDeletingLastPathComponent()
	
	-- Before doing anything else, check that an "Anteriormente." folder exists in the folder. If not, show a message and return the script's input.
	set AnteriormenteURL to folderURL's URLByAppendingPathComponent:("Anteriormente.")
	if ((AnteriormenteURL's checkResourceIsReachableAndReturnError:(missing value)) as boolean) then
		if ((AnteriormenteURL's resourceValuesForKeys:({|⌘|'s NSURLIsDirectoryKey, |⌘|'s NSURLIsPackageKey}) |error|:(missing value)) as record is not {NSURLIsDirectoryKey:true, NSURLIsPackageKey:false}) then
			display dialog "The item \"Anteriormente.\" isn't a folder!"
			return input
		end if
	else
		display dialog "The folder \"Anteriormente.\" doesn't exist in this folder!"
		return input
	end if
	
	-- Get NSURLs to every visible item in the folder and include their 'dates added'.
	set fileManager to |⌘|'s class "NSFileManager"'s defaultManager()
	set dateAddedKey to |⌘|'s NSURLAddedToDirectoryDateKey
	set contentURLs to (fileManager's contentsOfDirectoryAtURL:(folderURL) includingPropertiesForKeys:({dateAddedKey}) options:(|⌘|'s NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value))
	-- Filter out URLs to items named "Anteriormente." or "NO GUARDAR"
	set nameFilter to |⌘|'s class "NSPredicate"'s predicateWithFormat:("NOT lastPathComponent IN %@") argumentArray:({{"Anteriormente.", "NO GUARDAR"}})
	set filteredURLs to contentURLs's filteredArrayUsingPredicate:(nameFilter)
	
	-- Set up the cut-off date with which to compare the 'dates added'.
	set XDaysAgo to |⌘|'s class "NSDate"'s dateWithTimeIntervalSinceNow:(-X * days)
	if (daysMeansCalendarDays) then set XDaysAgo to |⌘|'s class "NSCalendar"'s currentCalendar()'s startOfDayForDate:(XDaysAgo)
	
	-- Deal with each of the URLs in turn.
	set output to {} -- For aliases to the moved items.
	repeat with thisURL in filteredURLs
		-- Get this item's 'date added', if any.
		set {noProblem, dateAdded} to (thisURL's getResourceValue:(reference) forKey:(dateAddedKey) |error|:(missing value))
		if (noProblem) then
			if (dateAdded is missing value) then
				-- No 'date added'. Move the item to the "Anteriormente." folder if the script's configured to do so in this situation.
				if (movingWhenNoDateAdded) then set end of output to moveItem(fileManager, thisURL, AnteriormenteURL)
			else
				-- Otherwise move the item if the date added is earlier than the cutoff date.
				if ((dateAdded's timeIntervalSinceDate:(XDaysAgo)) < 0) then set end of output to moveItem(fileManager, thisURL, AnteriormenteURL)
			end if
		end if
	end repeat
	
	return output
end moveOldItems

(* Move an item to another folder, keeping its original name. Return an alias to the result. *)
on moveItem(fileManager, sourceURL, destinationFolderURL)
	set destinationURL to destinationFolderURL's URLByAppendingPathComponent:(sourceURL's lastPathComponent)
	-- If an item with the same name already exists in the target folder, zap it or move it to the trash according to the script's configuration settings.
	if ((destinationURL's checkResourceIsReachableAndReturnError:(missing value)) as boolean) then
		if (zappingReplacedItems) then
			fileManager's removeItemAtURL:(destinationURL) |error|:(missing value)
		else
			fileManager's trashItemAtURL:(destinationURL) resultingItemURL:(missing value) |error|:(missing value)
		end if
	end if
	-- Move the item.
	fileManager's moveItemAtURL:(sourceURL) toURL:(destinationURL) |error|:(missing value)
	
	return destinationURL's |path|() as string as POSIX file as alias
end moveItem

Nigel,

If it helps, you can get the added date using NSURL’s NSURLAddedToDirectoryDateKey resource key.

Thanks, Shane! I tried various searches on the Xcode documentation and none of them turned that up. It would certainly shorten the script. I’ll look into it now. I presume that the vague warning “This property is not supported by all volumes.” is nothing to worry about where items are known to have ‘dates added’.

I’d guess so – the same wording is used for several keys added in 10.10. (I probably should have mentioned it’s only in 10.10+.)

OK. I’ve now updated the script in post #9 above.

And I’ve updated it again this morning to correct a couple of goofs introduced yesterday. :expressionless: