Dictionary containing numeric data?

I'm trying to write a macro that periodically checks the files in a folder to see if any of their modification dates have changed. I'm creating a dictionary whose keys are the folder's file names and whose values are the files' modification dates. (I'm not converting the dates -- only using UNIX time.) When I try to store a UNIX time in the dictionary, the only thing that gets placed into the dictionary is the name of the variable that stores the UNIX time, not the time itself. I've tried many combinations of %Variable%Time% and %Dictionary[Filename,Time]%, but nothing seems to work.
So here's my question, how can I store a file's modification date in a dictionary and later compare that value with a newly-retrieved modification date?

Dictionary values are text. The Set Dictionary Value action takes a token Text Field, so if the variable Time has the modification time, then the value field should be %Variable%Time%.

To compare it, assuming the variable Time has the current value, you can use the Variable condition and check it is the Dictionary token, %Dictionary[DictionaryName,%Variable%FileName%].


That is a good use of dictionaries. Once you get your macro working, I presume you are planning to use a Periodic Trigger to make it run. But don't forget, macros can have more than one trigger, and in this case you could probably get it to trigger more quickly (at least for new files) if you add a second trigger to your macro that looks like this:

This way the macro will also run whenever a new file is added. Just one thing... whenever a macro can potentially run twice, you should start the macro with a Semaphore Lock action to prevent it from running two copies at the same time, which could cause problems with global variables or dictionaries.

One more thing. You may want to delete the item from your dictionary when files are removed, and you can easily catch that situation with this (different) trigger:

You can "delete a dictionary entry" simply by assigning it an empty string value.

Perhaps I'm missing some nuance here, but once you've run the macro the first time any file that's changed will have a modification date more recent than the last time the macro was run.

So no need to store all that file info, just a single value to compare against.

Unless, of course, your modifications include setting time stamps to sometime in the past!

If you want to know about files being added/removed you could do the same but using the parent folder's modification time -- though you'd also have to maintain a list of files to compare the current contents against to find out what's changed. At that stage you're better off using @Airy's trigger (which can fire on removal as well as addition).

Well, I thought I had it fixed thanks to your great suggestions. But after an effort to make some slight improvements, it's not working and I have vertigo from trying to debug it. I want a macro that makes duplicates of any files in a certain directory that have been modified since the last time the macro was executed. When I run this macro, there doesn't seem to be any rhyme or reason concerning which files get duplicated. Also, the macro doesn't make the duplicates read-only. Finally, I don't know if there's a problem when I create a brand new file in that directory. Please look over my macro and tell me explicitly how to fix it. (I write KM scripts only rarely, so I don't know the scripting language very well.)

I did a quick read of it. I think I spotted two mistakes. But that doesn't mean I spotted all the mistakes.

  1. In your "Execute Shell Script" action, you cannot pass the variable to the shell using %Variable%%, you have to pass it using $KMVAR_VarName. There is a page on the KM wiki that explains how to pass variables to a shell.
  2. You are saving the time in a dictionary, but I don't see anywhere where you retrieve the value stored in the dictionary. Check the KM wiki for instructions on how to get data stored in a dictionary.

One more small error: Your if statement has two checks comparing Difference to zero. They don't do the exact same thing, but they do similar things. You should probably delete one of them.

There could be other mistakes. I did not test your macro, I just skimmed over it.

This will be difficult unless you upload your actual macro rather than a screen shot of it. But you've a logic error:

"If Difference > 0 OR Difference is not 0" will be true whenever Difference is not 0 -- either the first part is redundant and you want to copy every file with a different modification date, or the second part is wrong because you want to copy only those files modified more recently than the stored date.

Another problem is that you are using Filename to iterate through the collection -- your "original" files. But you use it again, within the same loop, to see if the file needs to be made read-only -- you are only checking your originals, not any copies you made.

Do you need to have the copies in the same directory as the originals? If not, you could probably replace all this with a single rsync command. And why make the duplicates read-only? If you want to "lock" them, both more obvious and more easily undone in the Finder, use chflags instead: chflags uchg /path/to/file

That's not to say what you are doing is wrong! But the "why" often informs the "how" which, in turn, determines the macro.

Thanks for your help so far. I've attached an XML file containing my work with some fixes (based on some of your comments). I'm guessing that getting values from the SavedModDates dictionary isn't working.
CopyFiles.xml.zip (3.8 KB)

I think I solved the problem. Use Set Variable "ThisSavedModDate" to Text "%Dictionary ..."
instead of to Calculation.