Folder trigger with dynamically created folder?

Is there a better way to do this?

I have a folder with a KM trigger that will open any added file in Yoink, a desktop tray app. It works great.

I started using Elmedia Player for video screenshots. I want to send the screenshots to the Yoink folder. On the first screenshot of a video, Elmedia creates a new folder with a unique name
(videoName+timeStamp) and saves the screenshot file inside. For the second screenshot on, it adds the file to the folder. All the files are named "screenshot1","screenshot2" etc.

I can't use the new folder as a KM trigger, because the name is always unique. Also, Yoink expects unique file names. I'll get unexpected results if I hand Yoink multiple files named "screenshot1". This could happen if I captured from several videos in a sitting.

My solution in the macro below was to use the enclosing folder as a KM trigger, rename and move the file(s) to the Yoink folder, and trash the enclosing folder. I used a For Each in case somehow there are more than one file in the folder.

5958dfe1006695ae0bb379c2914ed2f38fac78b2_2_690x616

This works, but I wonder if there is some way of using the newly created folder as trigger, or otherwise make this more elegant.

Thanks!

The above macro worked sometimes, sometimes it failed to move the screenshot into the Yoink folder, and sometimes it moved the screenshot, but it arrived with zero k data. Through trial and error, I discovered that it works consistently if I added a 1-second Pause after the Set Variable and before the For Each Item.

Oddly, if I changed the Pause to .5 seconds, the screenshot arrives in the Yoink folder with zero k data.

@peternlewis how does the Pause affect this process? Doesn't KM wait until the Set Variable function is done before it starts For Each Item? Thanks.

This might be too obvious, but... Why not change Elmedia Player's default save location to your Yoink folder?

Screenshot

...or is it that you don't want them to be in folders when they arrive?

One thing you might try is to select ignore partial or changing files under the folder trigger; otherwise, I can't see any major problems with your macro.

Not that it matters, but you don't need either of the set variable actions. You can use the TriggerValue token directly when trashing the folder and you can add FrameGrab-%ICUDateTime%ssSSS%.png straight after the / in the move to path.

Because my goal is to have the screenshots in Yoink rather than their containing folder.

Thanks for that refinement. Every bit of efficiency helps.

I've just had a look at Yoink, so I think I understand now.

Only thing I can think of that might be causing the 0kb files is that the macro might be running after the folder is created, but before or during the creation of the files within.

You could try adding a pause until file exists at the path, TriggerValue.

Building off work with @noisneil and @Zabobon in another thread -- how about using a folder-watching macro to spy on the first folder, and re-write a second macro's trigger to point to any newly-created subfolder? The second macro is the one that'll do your actual processing, like moving files.

As it stands, the macros look at a folder on your Desktop called "Elmedia Output" -- change the folder of the trigger of "Main Watcher" to suit your situation but don't change "Subfolder Watcher"s trigger.

As written the "Subfolder" macro will check the "item" added -- if it's a folder it will flash a notification for each file in that folder (none if the folder is empty), but if it's a file it will notify you of the file name. That's because I don't know the order in which the subfolder and screen shot are written this should cope regardless of whether Elmedia creates a folder (triggering the first macro to change the second) then a file (spotted by the second macro), or a folder with a file (for which the second macro may not have had its trigger set in time to respond).

You can replace the "Display text" actions with whatever you want to do. There's probably a way of doing the processing without duplicating the steps for both cases, but let's see if it works first...

This is new ground for me and, while I've done some tests, you should check it very carefully before using it in anger!

Watch Elmedia Screenies Macros.kmmacros (7.0 KB)

(The meat is in the AppleScript, most of which doesn't show in an image, so no piccy included...)

1 Like

Yes, the Set Variable function if fully synchronous.

You could move the Pause to before the Set Variable, and the result will be the same.

The pause is affecting how long until the For Each action works and allowing the file operations to complete. The issue is related to your trigger and the behaviour of the applications saving the file, not the Set Variable action.

1 Like

I was unable to make this work, likely because my knowledge is limited. I tried pausing until a file/folder/something exists at TriggerValue, there was no pause, and the KM macro trashed the enclosing folder before the screenshot could be written to it.

As Peter suggested, I tried moving the 1-second pause earlier based on the idea that the macro needs to wait for the folder and screenshot to be written. Moving the pause earlier worked fine.

I do wish I understood how to tell KM to Pause until the file operations were completed.

Thanks for taking the time to put this together. This is exactly what I wanted to do from the start, but I had no idea how to do it.

Is there a way to assign a trigger to another macro using just KM actions, and no custom scripting?

It is not necessarily possible.

What trigger are you using?

Apologies. I was out and about and clutching at straws, so ignore that suggestion. Seems as though @peternlewis and @Nige_S have steered you right. :+1:t3:

1 Like

KM can macro itself, but (I think) you'd have to use UI scripting -- keystrokes and possibly image detection -- to do this as there's no "Edit trigger" menu item. You could, for example, select the macro, switch to edit mode if you aren't in that already, tab the required number of times to get into the right dialog...

But as a rule of thumb -- "direct" KM actions (like "Select Menu Item") and scripts will be much more robust than imitating human interaction with the UI, so it's better to use them when you can.

1 Like

A folder trigger.

The app creates a uniquely named folder and then writes a PNG file to that folder.

I have KM watch the existing enclosing folder for the new folder to be added. I don't know the name of the new folder in advance, so I can't define it as a folder trigger.

Since I can't watch the new folder for the PNG file to be added, I have to add a 1-second pause to give the file system enough time to finish before the macro continues processing the new PNG file.

I'd prefer to have a method to Pause until the PNG file has been written, in case there is some delay in writing the file that takes more than 1 second.

Unfortunately there is no reasonable way to detect that the file has been written.

You could, possibly, do something like this:

  • Trigger on folder creation
  • Pause until png exists
  • Pause until the shell command lsof -n -F n does not contain the path to the png.

That might work ok.

Thanks for the help, Peter.

How do I do that?

I tried using Pause Until with the Trigger Path, but it doesn't look inside the folder.

I couldn't figure out how to use a count loop to pause until it wasn't empty.

The next line in @peternlewis post:

  • Pause until the shell command lsof -n -F n does not contain the path to the png.

He's given you a three-step recipe, not three different options. The last step is a "Pause until..." action using a "Script Condition" set to "The shell script text". The script text is the lsof command above (or below!) and the last option is set to "does not contain" and your file path:

lsof generally takes a while to complete, even if you limit it to the folder Elmedia is making its screenshot folders in with
lsof -n -F n +D /path/to/folder
...so you might find it easier to add a 5 second pause!

Another, although more fragile, way to do this is to get the size of the new file every second and assume that if the file size hasn't changed between checks then the writing has finished. You can do that with KM's "Get File Attribute" action.

1 Like

Thanks for the explanation, Nige. I did understand it was a three-step process. I'm sorry I wasn't clear enough with my post.

My problem is with this step:

  • Pause until png exists

I've got the path of the new folder from the TriggerValue, but how do I use that to make KM look inside that folder and evaluate whether the PNG exists?

I found a post from @peternlewis in 2016 suggesting a While loop, so I tried it -- but I couldn't get it to work. This is what I came up with:

It zips through without any pause at all, and I end up with a zero k PNG file.

I know I could solve this with a 5-second pause. I'd like to learn the underlying principles for making this a decision-based pause. It's kind of confounding to me that this situation (renaming and moving a file being written inside a new folder) is so hard to manage in KM.

It reveals my ignorance.

I know exactly where the folder will be created, and I know a string the folder name will always contain. I'm surprised that I can't define a folder trigger with wildcards or a grep search.

I'm eager to learn if there is a non-scripting way to determine when the PNG file exists and is done being written.

Thanks for your help.

What is the name of the .png file inside the folder?

If the name is unknown, then you'll first have to pause until the file appears with the name.

Something like:

  • Set variable PNGPath to ""
  • While variable PNGPath is empty
    • For Each variable Path in folder %TriggerValue%
      • If variable Path ends with ".png"
        • Set variable PNGPath to “%Variable%Path%”

Thanks for the suggestion; I finally got it to work.

I got the unique name of the folder from TriggerValue;
If the folder is created and triggers the macro, then the PNG is always named "screenshot.png" ;
The path of the PNG = TriggerValue/screenshot.png;
Pause until the PNG exists
Pause until lsof does not contain the path of the trigger folder name
Then I'm golden to do the rest of the file manipulations.

1 Like

That's tricky, and a reason why I suggested my "watch the parent, set the second watcher's trigger" method. With that your "processor" will be triggered every time Elmedia adds a new file so no need to check -- although you may have to put in a "wait" loop until Elmedia has finished writing the file, depending on how the KM action checks for "completeness" and how Elmedia does the writing.

If you are avoiding that because of "custom scripting" -- @peternlewis has deliberately made parts of KM available to AppleScript and we're only using those parts, so it isn't like we're going against the developer's intentions here! If you're avoiding it because it didn't work -- we might be able to fix that...

The advantage of watching the "child" folder is that you don't have to leave a KM macro running to check for further additions to that folder -- it'll pick up the next screen shot for that video whether you do it straight away or take a tea break between screenies!