Is it possible to process all items in a Smart Folder? As an example, here's a Smart Folder that displays only items (in this case, folders) with a certain Finder tag. The tagged items might be from anywhere on any of my drives.
If it is possible to delete files from the Dropbox folder when their parent directories become untagged, it won't be simple, so I might quit while I'm ahead!
tell application "Finder"
# tell front Finder window -- if you want to use the front window.
tell Finder window "Pending"
set smartFolderContents to its items
end tell
end tell
Tested on macOS 10.14.6
I'd think you could do that directly with Hazel...
You'd have to periodically scan the files in the Dropbox directory and test the tagged-status of their parent directories.
Keyboard Maestro would be slow if you have a lot of files to scan, so I would probably use the shell or AppleScript or both.
This task might be a bit tedious, but it should be quite doable.jb
Thankyou Chris! That AppleScript will no doubt be very handy for other things! However, what I like about Hazel is that it can actually monitor a Smart Folder as though it were a regular folder, and can therefore trigger a macro whenever anything is added to it by being tagged. I can't find a way to do that with KM.
This got my brain going and I came up with something. At the end of the macro, it adds the tagged file/folder path as a comment in the copied file attributes.
Whenever I want to tidy up the Dropbox folder (by trashing any files whose originals have been untagged), I run a second macro which references the comments in all the copied .m4a files.
It would be nice if this was triggered whenever a file was removed from the Smart Folder (i,e, untagged), but I can't figure out how to do that. Still, this is pretty nice! It means all I have to do is maintain my tags and occasionally do a tidy-up. Getting the tagged files into the Dropbox folder is more important to me than keeping extraneous ones out.
Right. KM cannot automatically monitor a smart folder – you'd have to poll it with a periodic trigger, store the result, poll it again, and do a diff to see if it had changed.
Doesn't Hazel have the ability to detect whether a file was removed? If not – it would seem to be a very strange limitation...
Hmm. Had a good read of the manual and scoured the Noodlesoft forum but could only find conditions for whether the number of files was above or below a certain number or whether that number had changed. Nothing on whether the number had increased or reduced.
After a bit of back and forth, I got a definitive answer on the Noodlesoft forum. Hazel can tell if a file count has changed, but not whether it has increased or decreased. As you say, an oversight.
I'm confused. It looks from your screenshot above as if Hazel can return a file path to a newly-tagged file/folder after it appears in the Smart Folder (theFile that's then used as the parameter).
Presumably when something is removed theFile is either the path to what's removed, the path to the parent, empty, or something else equally obviously different to the "file/folder added" value? That, in conjunction with a file count change, should be enough to determine something was removed.
Whether you can do anything about it is another matter. But, at its heart, a Smart Folder is a constantly updating Spotlight search -- maybe you could use mdls with the appropriate arguments for that Smart Folder and compare that to a Dropbox file listing. Or, as Chris suggested earlier, keep a running list of Smart Folder contents and diff the current state against the previous one.
Sorry Chris, my bad. I intentionally left that out so as not to post details of the project name associated with the Smart Folder on here... but yes, that's right.
Thanks for confirming. It sounds like perhaps there are a few strategies for dealing with Smart Folders, but for now I'll stick with the manual cleanup. No biggie. Thanks all.
G'ah! Apologies for the brain-fart... You'd have thought I'd have realised while typing it that mdls is to list (ls) metadata (md). The correct command, of course, is mdfind.
But that sent me back to the man page for mdfind and, lo and behold:
-s <name> Show contents of smart folder <name>
So if you've a Smart Folder called "Desktop PDFs" you can list the contents with
mdfind -s "Desktop PDFs"
So I'm thinking that, since you're you and are probably untagging with a macro, you could do something like
save output of mdfind to variable "A"
untag files/folders
save output of mdfind to variable "B"
for each line in "A"
if not in "B" remove from Dropbox
end if
I'm not sure it would solve my particular problem. The sticking point isn't how to compare and delete; it's how to trigger it automatically when a tag is removed.
The manual method I'm currently using does the following:
Check the comment attribute for each file in the Dropbox Folder. The comment was set to the original file's path when copied over initially.
Use the comment path to check the original file for the tag NEXT.
If the tag is not found, delete the corresponding file in the Dropbox folder.
The reason I ended up with this is that I'm not copying the tagged folders in the Saved Search; I'm copying any mp3 or m4a files found within them.
I did just think of something though. Why not run the Dropbox cleanup at the start of the copy macro? That way, whenever I tag a file it deletes any copies of files from untagged folders and then copies files from tagged folders. It's not perfect, but it does mean I don't need to manually intervene.
I was assuming you were removing tags with a macro as well. If not then yes, you could do it either do it as part of the copy macro or run it on a periodic trigger. The latter would be where mdfind would be good, as that would be relatively quick and a low cost way of comparing "now" to "5 minutes ago".